From 7ac9bac33d3e4bf321c541dc770ac9c8af6905c5 Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Sun, 2 Mar 2003 05:24:21 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'unlabeled-1.2.770'. --- lustre/.cvsignore | 15 - lustre/BUGS | 15 - lustre/BUILDING | 25 - lustre/COPYING | 352 --- lustre/ChangeLog | 359 --- lustre/FDL | 355 --- lustre/Makefile.am | 37 - lustre/README | 8 - lustre/Rules | 25 - lustre/archdep.m4 | 127 - lustre/autogen.sh | 6 - lustre/cobd/.cvsignore | 3 - lustre/cobd/Makefile.am | 15 - lustre/cobd/cache_obd.c | 346 --- lustre/cobd/lproc_cache.c | 89 - lustre/conf/.cvsignore | 2 - lustre/conf/Makefile.am | 15 - lustre/conf/lustre.dtd | 125 - lustre/conf/lustre2ldif.xsl | 233 -- lustre/conf/slapd-lustre.conf | 12 - lustre/conf/top.ldif | 4 - lustre/configure.in | 185 -- lustre/doc/.cvsignore | 23 - lustre/doc/Makefile.am | 124 - lustre/doc/VERSIONING | 91 - lustre/doc/chbar.sh | 243 -- lustre/doc/lconf.lyx | 145 - lustre/doc/lctl.lyx | 662 ----- lustre/doc/lmc.lyx | 444 --- lustre/doc/postbar | 151 - lustre/doc/tex2pdf | 3043 -------------------- lustre/extN/.cvsignore | 19 - lustre/extN/Makefile.am | 144 - lustre/extN/ext3-2.4-ino_t.diff | 138 - lustre/extN/ext3-2.4.18-fixes.diff | 353 --- lustre/extN/ext3-2.4.18-ino_sb_macro.diff | 1554 ---------- lustre/extN/ext3-largefile.diff | 23 - lustre/extN/ext3-unmount_sync.diff | 59 - lustre/extN/ext3-use-after-free.diff | 65 - lustre/extN/extN-2.4.18-exports.diff | 11 - lustre/extN/extN-2.4.18-ino_sb_fixup.diff | 33 - lustre/extN/extN-iget-debug.diff | 48 - lustre/extN/extN-misc-fixup.diff | 23 - lustre/extN/extN-noread.diff | 225 -- lustre/extN/extN-san.diff | 88 - lustre/extN/extN-wantedi.diff | 163 -- lustre/extN/htree-ext3-2.4.18.diff | 1201 -------- lustre/extN/linux-2.4.18ea-0.8.26.diff | 1769 ------------ lustre/extN/patch-2.4.18-chaos22 | 165 -- lustre/include/.cvsignore | 11 - lustre/include/config.h.in | 10 - lustre/include/liblustre.h | 431 --- lustre/include/linux/.cvsignore | 15 - lustre/include/linux/Makefile | 7 - lustre/include/linux/lprocfs_status.h | 187 -- lustre/include/linux/lustre_debug.h | 53 - lustre/include/linux/lustre_dlm.h | 483 ---- lustre/include/linux/lustre_export.h | 52 - lustre/include/linux/lustre_fsfilt.h | 170 -- lustre/include/linux/lustre_ha.h | 64 - lustre/include/linux/lustre_handles.h | 39 - lustre/include/linux/lustre_idl.h | 624 ---- lustre/include/linux/lustre_import.h | 50 - lustre/include/linux/lustre_lib.h | 649 ----- lustre/include/linux/lustre_lite.h | 288 -- lustre/include/linux/lustre_mds.h | 302 -- lustre/include/linux/lustre_net.h | 450 --- lustre/include/linux/obd.h | 417 --- lustre/include/linux/obd_cache.h | 13 - lustre/include/linux/obd_class.h | 978 ------- lustre/include/linux/obd_echo.h | 41 - lustre/include/linux/obd_ext2.h | 49 - lustre/include/linux/obd_filter.h | 96 - lustre/include/linux/obd_lov.h | 28 - lustre/include/linux/obd_ost.h | 44 - lustre/include/linux/obd_ptlbd.h | 30 - lustre/include/linux/obd_snap.h | 29 - lustre/include/linux/obd_snap_support.h | 85 - lustre/include/linux/obd_support.h | 229 -- lustre/include/linux/obd_trace.h | 20 - lustre/install-sh | 251 -- lustre/kernel_patches/README | 708 ----- lustre/kernel_patches/patches/dev_read_only.patch | 73 - .../kernel_patches/patches/dev_read_only_hp.patch | 77 - lustre/kernel_patches/patches/exports.patch | 57 - lustre/kernel_patches/patches/exports_hp.patch | 56 - lustre/kernel_patches/patches/ext3-xattr-2.5.patch | 2690 ----------------- .../kernel_patches/patches/invalidate_show.patch | 104 - .../kernel_patches/patches/iod-rmap-exports.patch | 71 - lustre/kernel_patches/patches/jbd-transno-cb.patch | 240 -- .../patches/kmem_cache_validate.patch | 119 - .../patches/kmem_cache_validate_hp.patch | 105 - lustre/kernel_patches/patches/lustre-2.5.patch | 507 ---- lustre/kernel_patches/patches/lustre_version.patch | 12 - .../patches/patch-2.4.18-hp1_pnnl18.2.8qsnet.patch | 1673 ----------- .../patches/uml_check_get_page.patch | 31 - .../kernel_patches/patches/uml_compile_fixes.patch | 18 - lustre/kernel_patches/patches/uml_no_panic.patch | 31 - lustre/kernel_patches/patches/vanilla-2.4.18.patch | 1672 ----------- lustre/kernel_patches/patches/vanilla-2.4.19.patch | 1576 ---------- .../patches/vfs_intent-2.4.18-18.patch | 1448 ---------- lustre/kernel_patches/patches/vfs_intent.patch | 1158 -------- lustre/kernel_patches/patches/vfs_intent_hp.patch | 1526 ---------- lustre/kernel_patches/pc/dev_read_only.pc | 3 - lustre/kernel_patches/pc/dev_read_only_hp.pc | 3 - lustre/kernel_patches/pc/exports.pc | 4 - lustre/kernel_patches/pc/exports_hp.pc | 4 - lustre/kernel_patches/pc/invalidate_show.pc | 5 - lustre/kernel_patches/pc/iod-rmap-exports.pc | 6 - lustre/kernel_patches/pc/jbd-transno-cb.pc | 4 - lustre/kernel_patches/pc/kmem_cache_validate.pc | 5 - lustre/kernel_patches/pc/kmem_cache_validate_hp.pc | 5 - lustre/kernel_patches/pc/lustre-2.5.pc | 11 - lustre/kernel_patches/pc/lustre_version.pc | 1 - .../pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc | 23 - lustre/kernel_patches/pc/uml_check_get_page.pc | 2 - lustre/kernel_patches/pc/uml_compile_fixes.pc | 2 - lustre/kernel_patches/pc/uml_no_panic.pc | 2 - lustre/kernel_patches/pc/vanilla-2.4.18.pc | 23 - lustre/kernel_patches/pc/vanilla-2.4.19.pc | 19 - lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc | 9 - lustre/kernel_patches/pc/vfs_intent.pc | 8 - lustre/kernel_patches/pc/vfs_intent_hp.pc | 8 - lustre/kernel_patches/prepare_tree.sh | 88 - lustre/kernel_patches/scripts/added-by-patch | 14 - lustre/kernel_patches/scripts/apatch | 98 - lustre/kernel_patches/scripts/combine-applied | 43 - lustre/kernel_patches/scripts/combine-series | 43 - lustre/kernel_patches/scripts/cvs-take-patch | 78 - lustre/kernel_patches/scripts/export_patch | 55 - lustre/kernel_patches/scripts/extract_description | 87 - lustre/kernel_patches/scripts/fpatch | 53 - lustre/kernel_patches/scripts/import_patch | 102 - lustre/kernel_patches/scripts/inpatch | 27 - lustre/kernel_patches/scripts/linus-patch | 26 - lustre/kernel_patches/scripts/mpatch | 101 - lustre/kernel_patches/scripts/new-kernel | 82 - lustre/kernel_patches/scripts/p0-2-p1 | 10 - lustre/kernel_patches/scripts/p_diff | 60 - lustre/kernel_patches/scripts/patchdesc | 21 - lustre/kernel_patches/scripts/patchfns | 239 -- lustre/kernel_patches/scripts/pcpatch | 45 - lustre/kernel_patches/scripts/poppatch | 70 - lustre/kernel_patches/scripts/prep-patch | 18 - lustre/kernel_patches/scripts/pstatus | 156 - lustre/kernel_patches/scripts/ptkdiff | 46 - lustre/kernel_patches/scripts/pushpatch | 84 - lustre/kernel_patches/scripts/refpatch | 31 - lustre/kernel_patches/scripts/removed-by-patch | 14 - lustre/kernel_patches/scripts/rename-patch | 20 - lustre/kernel_patches/scripts/rolled-up-patch | 30 - lustre/kernel_patches/scripts/rpatch | 69 - lustre/kernel_patches/scripts/split-patch | 29 - lustre/kernel_patches/scripts/tag-series | 41 - lustre/kernel_patches/scripts/toppatch | 27 - lustre/kernel_patches/scripts/touched-by-patch | 32 - lustre/kernel_patches/scripts/unitdiff.py | 223 -- lustre/kernel_patches/series/chaos | 7 - lustre/kernel_patches/series/hp-pnnl | 7 - lustre/kernel_patches/series/rh-2.4.18-18 | 10 - lustre/kernel_patches/series/rh-8.0 | 9 - lustre/kernel_patches/series/vanilla-2.4.18 | 2 - lustre/kernel_patches/series/vanilla-2.4.19 | 3 - lustre/kernel_patches/series/vanilla-2.5 | 2 - lustre/kernel_patches/txt/dev_read_only.txt | 3 - lustre/kernel_patches/txt/exports.txt | 3 - lustre/kernel_patches/txt/exports_hp.txt | 3 - lustre/kernel_patches/txt/invalidate_show.txt | 3 - lustre/kernel_patches/txt/kmem_cache_validate.txt | 3 - lustre/kernel_patches/txt/lustre_version.txt | 3 - lustre/kernel_patches/txt/uml_check_get_page.txt | 3 - lustre/kernel_patches/txt/uml_compile_fixes.txt | 3 - lustre/kernel_patches/txt/uml_no_panic.txt | 3 - lustre/kernel_patches/txt/vfs_intent.txt | 3 - lustre/kernel_patches/which_patch | 10 - lustre/ldlm/.cvsignore | 3 - lustre/ldlm/Makefile.am | 24 - lustre/ldlm/l_lock.c | 116 - lustre/ldlm/ldlm_extent.c | 114 - lustre/ldlm/ldlm_lock.c | 1169 -------- lustre/ldlm/ldlm_lockd.c | 901 ------ lustre/ldlm/ldlm_request.c | 873 ------ lustre/ldlm/ldlm_resource.c | 586 ---- lustre/ldlm/ldlm_test.c | 648 ----- lustre/lib/.cvsignore | 8 - lustre/lib/Makefile.am | 4 - lustre/lib/client.c | 406 --- lustre/lib/mds_updates.c | 604 ---- lustre/lib/obd_pack.c | 83 - lustre/lib/simple.c | 270 -- lustre/lib/target.c | 523 ---- lustre/liblustre/.cvsignore | 9 - lustre/liblustre/Makefile.am | 18 - lustre/liblustre/libtest.c | 114 - lustre/llite/.cvsignore | 8 - lustre/llite/Makefile.am | 16 - lustre/llite/commit_callback.c | 137 - lustre/llite/dcache.c | 224 -- lustre/llite/dir.c | 827 ------ lustre/llite/file.c | 914 ------ lustre/llite/lproc_llite.c | 182 -- lustre/llite/namei.c | 1201 -------- lustre/llite/recover.c | 56 - lustre/llite/rw.c | 505 ---- lustre/llite/super.c | 745 ----- lustre/llite/super25.c | 760 ----- lustre/llite/symlink.c | 170 -- lustre/llite/sysctl.c | 70 - lustre/lov/.cvsignore | 3 - lustre/lov/Makefile.am | 24 - lustre/lov/lov_obd.c | 1691 ----------- lustre/lov/lov_pack.c | 352 --- lustre/lov/lproc_lov.c | 177 -- lustre/mdc/.cvsignore | 8 - lustre/mdc/Makefile.am | 20 - lustre/mdc/lproc_mdc.c | 63 - lustre/mdc/mdc_reint.c | 230 -- lustre/mdc/mdc_request.c | 790 ----- lustre/mds/.cvsignore | 8 - lustre/mds/Makefile.am | 24 - lustre/mds/handler.c | 1857 ------------ lustre/mds/lproc_mds.c | 105 - lustre/mds/mds_fs.c | 396 --- lustre/mds/mds_lov.c | 255 -- lustre/mds/mds_open.c | 379 --- lustre/mds/mds_reint.c | 1175 -------- lustre/missing | 336 --- lustre/mkinstalldirs | 40 - lustre/nodist | 21 - lustre/obdclass/.cvsignore | 8 - lustre/obdclass/Makefile.am | 39 - lustre/obdclass/class_obd.c | 896 ------ lustre/obdclass/debug.c | 161 -- lustre/obdclass/fsfilt.c | 107 - lustre/obdclass/fsfilt_ext3.c | 340 --- lustre/obdclass/fsfilt_extN.c | 547 ---- lustre/obdclass/fsfilt_reiserfs.c | 205 -- lustre/obdclass/genops.c | 547 ---- lustre/obdclass/lprocfs_status.c | 341 --- lustre/obdclass/lustre_handles.c | 166 -- lustre/obdclass/lustre_peer.c | 179 -- lustre/obdclass/statfs_pack.c | 115 - lustre/obdclass/sysctl.c | 140 - lustre/obdclass/uuid.c | 140 - lustre/obdecho/.cvsignore | 8 - lustre/obdecho/Makefile.am | 20 - lustre/obdecho/echo.c | 715 ----- lustre/obdecho/echo_client.c | 1166 -------- lustre/obdecho/lproc_echo.c | 54 - lustre/obdfilter/.cvsignore | 8 - lustre/obdfilter/Makefile.am | 22 - lustre/obdfilter/filter.c | 2700 ----------------- lustre/obdfilter/lproc_obdfilter.c | 76 - lustre/osc/.cvsignore | 8 - lustre/osc/Makefile.am | 29 - lustre/osc/lproc_osc.c | 62 - lustre/osc/osc_request.c | 1675 ----------- lustre/ost/.cvsignore | 8 - lustre/ost/Makefile.am | 22 - lustre/ost/lproc_ost.c | 42 - lustre/ost/ost_handler.c | 921 ------ lustre/ptlbd/.cvsignore | 3 - lustre/ptlbd/Makefile.am | 14 - lustre/ptlbd/blk.c | 257 -- lustre/ptlbd/client.c | 139 - lustre/ptlbd/main.c | 70 - lustre/ptlbd/rpc.c | 252 -- lustre/ptlbd/server.c | 108 - lustre/ptlrpc/.cvsignore | 9 - lustre/ptlrpc/Makefile.am | 19 - lustre/ptlrpc/client.c | 952 ------ lustre/ptlrpc/connection.c | 181 -- lustre/ptlrpc/events.c | 499 ---- lustre/ptlrpc/lproc_ptlrpc.c | 41 - lustre/ptlrpc/niobuf.c | 630 ---- lustre/ptlrpc/pack_generic.c | 144 - lustre/ptlrpc/recovd.c | 372 --- lustre/ptlrpc/recover.c | 282 -- lustre/ptlrpc/rpc.c | 311 -- lustre/ptlrpc/service.c | 501 ---- lustre/scripts/.cvsignore | 9 - lustre/scripts/Makefile.am | 10 - lustre/scripts/dodiff.sh | 5 - lustre/scripts/license-status | 26 - lustre/scripts/lustre | 95 - lustre/scripts/lustre.spec.in | 206 -- lustre/scripts/maketags.sh | 8 - lustre/scripts/nodelustre | 46 - lustre/scripts/system-profile.sh | 233 -- lustre/scripts/version_tag.pl | 171 -- lustre/tests/.cvsignore | 37 - lustre/tests/Makefile.am | 59 - lustre/tests/README | 85 - lustre/tests/acceptance-metadata-double.sh | 140 - lustre/tests/acceptance-metadata-single.sh | 146 - lustre/tests/acceptance-small.sh | 111 - lustre/tests/ba-echo.sh | 38 - lustre/tests/ba-mount.sh | 53 - lustre/tests/busy.sh | 7 - lustre/tests/checkstat.c | 314 -- lustre/tests/client-echo.cfg | 3 - lustre/tests/client-mount.cfg | 6 - lustre/tests/client-mount2.cfg | 10 - lustre/tests/cobd.sh | 41 - lustre/tests/common.sh | 713 ----- lustre/tests/compile.sh | 15 - lustre/tests/create.pl | 78 - lustre/tests/createdestroy.c | 224 -- lustre/tests/createmany.c | 98 - lustre/tests/createtest.c | 142 - lustre/tests/directio.c | 69 - lustre/tests/echo.sh | 49 - 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 | 1228 -------- 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 | 69 - lustre/tests/lkcdmap | 15 - lustre/tests/llcleanup.sh | 19 - lustre/tests/lldlm.sh | 40 - lustre/tests/llecho.sh | 17 - lustre/tests/llechocleanup.sh | 15 - 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 | 26 - lustre/tests/llmountcleanup.sh | 40 - lustre/tests/llrext3.sh | 10 - lustre/tests/llrmount.sh | 21 - lustre/tests/llrsetup.sh | 15 - lustre/tests/llsetup.sh | 15 - lustre/tests/llsimple.sh | 11 - lustre/tests/local.sh | 39 - lustre/tests/lov.sh | 32 - lustre/tests/lustre.cfg | 49 - lustre/tests/mcr-individual-ost-nogw-config.sh | 46 - lustre/tests/mcr-mds-failover-config.sh | 50 - lustre/tests/mcr-routed-config.sh | 93 - lustre/tests/mcr.sh | 45 - lustre/tests/mcreate.c | 23 - lustre/tests/mcrlov.sh | 52 - 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 | 30 - lustre/tests/mount2fs.sh | 43 - lustre/tests/multifstat.c | 62 - 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/open_delay.c | 27 - lustre/tests/openclose.c | 143 - lustre/tests/openme.c | 23 - lustre/tests/openunlink.c | 147 - lustre/tests/ostreq.sh | 37 - lustre/tests/recovery-cleanup.sh | 134 - lustre/tests/recovery-small.sh | 144 - lustre/tests/rename.pl | 78 - 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 | 111 - lustre/tests/runregression-mds.sh | 67 - lustre/tests/runregression-net.sh | 99 - lustre/tests/runslabinfo | 5 - lustre/tests/runtests | 130 - lustre/tests/runvmstat | 2 - lustre/tests/sanity.sh | 558 ---- lustre/tests/sanityN.sh | 113 - lustre/tests/snaprun.sh | 36 - lustre/tests/stat.c | 24 - lustre/tests/statmany.c | 215 -- lustre/tests/statone.c | 60 - lustre/tests/tbox.sh | 116 - lustre/tests/tchmod.c | 18 - lustre/tests/test.c | 101 - lustre/tests/test_brw.c | 209 -- lustre/tests/testreq.c | 141 - lustre/tests/toexcl.c | 77 - lustre/tests/trivial.sh | 11 - lustre/tests/truncate.c | 24 - lustre/tests/uml.sh | 89 - lustre/tests/wantedi.c | 49 - lustre/tests/writeme.c | 32 - lustre/utils/.cvsignore | 18 - lustre/utils/Makefile.am | 20 - lustre/utils/automatic-reconnect-sample | 34 - lustre/utils/ha_assist.sh | 5 - lustre/utils/ha_assist2.sh | 35 - lustre/utils/lconf.in | 2438 ---------------- lustre/utils/lctl.c | 257 -- lustre/utils/lfind.c | 331 --- lustre/utils/llanalyze | 278 -- lustre/utils/llparser.pm | 399 --- lustre/utils/lmc | 955 ------ lustre/utils/lstripe.c | 111 - lustre/utils/mds-failover-sample | 20 - lustre/utils/obd.c | 2044 ------------- lustre/utils/obdbarrier.c | 224 -- lustre/utils/obdctl.c | 103 - lustre/utils/obdctl.h | 72 - lustre/utils/obdio.c | 305 -- lustre/utils/obdiolib.c | 466 --- lustre/utils/obdiolib.h | 70 - lustre/utils/obdstat.c | 198 -- lustre/utils/parser.c | 722 ----- lustre/utils/parser.h | 74 - 424 files changed, 90757 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/cobd/.cvsignore delete mode 100644 lustre/cobd/Makefile.am delete mode 100644 lustre/cobd/cache_obd.c delete mode 100644 lustre/cobd/lproc_cache.c delete mode 100644 lustre/conf/.cvsignore delete mode 100644 lustre/conf/Makefile.am delete mode 100644 lustre/conf/lustre.dtd delete mode 100644 lustre/conf/lustre2ldif.xsl delete mode 100644 lustre/conf/slapd-lustre.conf delete mode 100644 lustre/conf/top.ldif 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-ino_t.diff 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/ext3-largefile.diff delete mode 100644 lustre/extN/ext3-unmount_sync.diff delete mode 100644 lustre/extN/ext3-use-after-free.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-iget-debug.diff delete mode 100644 lustre/extN/extN-misc-fixup.diff delete mode 100644 lustre/extN/extN-noread.diff delete mode 100644 lustre/extN/extN-san.diff delete mode 100644 lustre/extN/extN-wantedi.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/extN/patch-2.4.18-chaos22 delete mode 100644 lustre/include/.cvsignore delete mode 100644 lustre/include/config.h.in delete mode 100644 lustre/include/liblustre.h 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_fsfilt.h delete mode 100644 lustre/include/linux/lustre_ha.h delete mode 100644 lustre/include/linux/lustre_handles.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_cache.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_ptlbd.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/kernel_patches/README delete mode 100644 lustre/kernel_patches/patches/dev_read_only.patch delete mode 100644 lustre/kernel_patches/patches/dev_read_only_hp.patch delete mode 100644 lustre/kernel_patches/patches/exports.patch delete mode 100644 lustre/kernel_patches/patches/exports_hp.patch delete mode 100644 lustre/kernel_patches/patches/ext3-xattr-2.5.patch delete mode 100644 lustre/kernel_patches/patches/invalidate_show.patch delete mode 100644 lustre/kernel_patches/patches/iod-rmap-exports.patch delete mode 100644 lustre/kernel_patches/patches/jbd-transno-cb.patch delete mode 100644 lustre/kernel_patches/patches/kmem_cache_validate.patch delete mode 100644 lustre/kernel_patches/patches/kmem_cache_validate_hp.patch delete mode 100644 lustre/kernel_patches/patches/lustre-2.5.patch delete mode 100644 lustre/kernel_patches/patches/lustre_version.patch delete mode 100644 lustre/kernel_patches/patches/patch-2.4.18-hp1_pnnl18.2.8qsnet.patch delete mode 100644 lustre/kernel_patches/patches/uml_check_get_page.patch delete mode 100644 lustre/kernel_patches/patches/uml_compile_fixes.patch delete mode 100644 lustre/kernel_patches/patches/uml_no_panic.patch delete mode 100644 lustre/kernel_patches/patches/vanilla-2.4.18.patch delete mode 100644 lustre/kernel_patches/patches/vanilla-2.4.19.patch delete mode 100644 lustre/kernel_patches/patches/vfs_intent-2.4.18-18.patch delete mode 100644 lustre/kernel_patches/patches/vfs_intent.patch delete mode 100644 lustre/kernel_patches/patches/vfs_intent_hp.patch delete mode 100644 lustre/kernel_patches/pc/dev_read_only.pc delete mode 100644 lustre/kernel_patches/pc/dev_read_only_hp.pc delete mode 100644 lustre/kernel_patches/pc/exports.pc delete mode 100644 lustre/kernel_patches/pc/exports_hp.pc delete mode 100644 lustre/kernel_patches/pc/invalidate_show.pc delete mode 100644 lustre/kernel_patches/pc/iod-rmap-exports.pc delete mode 100644 lustre/kernel_patches/pc/jbd-transno-cb.pc delete mode 100644 lustre/kernel_patches/pc/kmem_cache_validate.pc delete mode 100644 lustre/kernel_patches/pc/kmem_cache_validate_hp.pc delete mode 100644 lustre/kernel_patches/pc/lustre-2.5.pc delete mode 100644 lustre/kernel_patches/pc/lustre_version.pc delete mode 100644 lustre/kernel_patches/pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc delete mode 100644 lustre/kernel_patches/pc/uml_check_get_page.pc delete mode 100644 lustre/kernel_patches/pc/uml_compile_fixes.pc delete mode 100644 lustre/kernel_patches/pc/uml_no_panic.pc delete mode 100644 lustre/kernel_patches/pc/vanilla-2.4.18.pc delete mode 100644 lustre/kernel_patches/pc/vanilla-2.4.19.pc delete mode 100644 lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc delete mode 100644 lustre/kernel_patches/pc/vfs_intent.pc delete mode 100644 lustre/kernel_patches/pc/vfs_intent_hp.pc delete mode 100755 lustre/kernel_patches/prepare_tree.sh delete mode 100755 lustre/kernel_patches/scripts/added-by-patch delete mode 100755 lustre/kernel_patches/scripts/apatch delete mode 100755 lustre/kernel_patches/scripts/combine-applied delete mode 100755 lustre/kernel_patches/scripts/combine-series delete mode 100755 lustre/kernel_patches/scripts/cvs-take-patch delete mode 100755 lustre/kernel_patches/scripts/export_patch delete mode 100755 lustre/kernel_patches/scripts/extract_description delete mode 100755 lustre/kernel_patches/scripts/fpatch delete mode 100755 lustre/kernel_patches/scripts/import_patch delete mode 100755 lustre/kernel_patches/scripts/inpatch delete mode 100755 lustre/kernel_patches/scripts/linus-patch delete mode 100755 lustre/kernel_patches/scripts/mpatch delete mode 100755 lustre/kernel_patches/scripts/new-kernel delete mode 100755 lustre/kernel_patches/scripts/p0-2-p1 delete mode 100755 lustre/kernel_patches/scripts/p_diff delete mode 100755 lustre/kernel_patches/scripts/patchdesc delete mode 100644 lustre/kernel_patches/scripts/patchfns delete mode 100755 lustre/kernel_patches/scripts/pcpatch delete mode 100755 lustre/kernel_patches/scripts/poppatch delete mode 100755 lustre/kernel_patches/scripts/prep-patch delete mode 100755 lustre/kernel_patches/scripts/pstatus delete mode 100755 lustre/kernel_patches/scripts/ptkdiff delete mode 100755 lustre/kernel_patches/scripts/pushpatch delete mode 100755 lustre/kernel_patches/scripts/refpatch delete mode 100755 lustre/kernel_patches/scripts/removed-by-patch delete mode 100755 lustre/kernel_patches/scripts/rename-patch delete mode 100755 lustre/kernel_patches/scripts/rolled-up-patch delete mode 100755 lustre/kernel_patches/scripts/rpatch delete mode 100755 lustre/kernel_patches/scripts/split-patch delete mode 100755 lustre/kernel_patches/scripts/tag-series delete mode 100755 lustre/kernel_patches/scripts/toppatch delete mode 100755 lustre/kernel_patches/scripts/touched-by-patch delete mode 100755 lustre/kernel_patches/scripts/unitdiff.py delete mode 100644 lustre/kernel_patches/series/chaos delete mode 100644 lustre/kernel_patches/series/hp-pnnl delete mode 100644 lustre/kernel_patches/series/rh-2.4.18-18 delete mode 100644 lustre/kernel_patches/series/rh-8.0 delete mode 100644 lustre/kernel_patches/series/vanilla-2.4.18 delete mode 100644 lustre/kernel_patches/series/vanilla-2.4.19 delete mode 100644 lustre/kernel_patches/series/vanilla-2.5 delete mode 100644 lustre/kernel_patches/txt/dev_read_only.txt delete mode 100644 lustre/kernel_patches/txt/exports.txt delete mode 100644 lustre/kernel_patches/txt/exports_hp.txt delete mode 100644 lustre/kernel_patches/txt/invalidate_show.txt delete mode 100644 lustre/kernel_patches/txt/kmem_cache_validate.txt delete mode 100644 lustre/kernel_patches/txt/lustre_version.txt delete mode 100644 lustre/kernel_patches/txt/uml_check_get_page.txt delete mode 100644 lustre/kernel_patches/txt/uml_compile_fixes.txt delete mode 100644 lustre/kernel_patches/txt/uml_no_panic.txt delete mode 100644 lustre/kernel_patches/txt/vfs_intent.txt delete mode 100644 lustre/kernel_patches/which_patch 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/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/liblustre/.cvsignore delete mode 100644 lustre/liblustre/Makefile.am delete mode 100644 lustre/liblustre/libtest.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_fs.c delete mode 100644 lustre/mds/mds_lov.c delete mode 100644 lustre/mds/mds_open.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/fsfilt.c delete mode 100644 lustre/obdclass/fsfilt_ext3.c delete mode 100644 lustre/obdclass/fsfilt_extN.c delete mode 100644 lustre/obdclass/fsfilt_reiserfs.c delete mode 100644 lustre/obdclass/genops.c delete mode 100644 lustre/obdclass/lprocfs_status.c delete mode 100644 lustre/obdclass/lustre_handles.c delete mode 100644 lustre/obdclass/lustre_peer.c delete mode 100644 lustre/obdclass/statfs_pack.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/ptlbd/.cvsignore delete mode 100644 lustre/ptlbd/Makefile.am delete mode 100644 lustre/ptlbd/blk.c delete mode 100644 lustre/ptlbd/client.c delete mode 100644 lustre/ptlbd/main.c delete mode 100644 lustre/ptlbd/rpc.c delete mode 100644 lustre/ptlbd/server.c 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/maketags.sh delete mode 100755 lustre/scripts/nodelustre delete mode 100755 lustre/scripts/system-profile.sh 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 100644 lustre/tests/acceptance-metadata-double.sh delete mode 100644 lustre/tests/acceptance-metadata-single.sh 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/busy.sh delete mode 100644 lustre/tests/checkstat.c 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 100755 lustre/tests/cobd.sh delete mode 100644 lustre/tests/common.sh delete mode 100644 lustre/tests/compile.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/createtest.c delete mode 100644 lustre/tests/directio.c delete mode 100755 lustre/tests/echo.sh 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/lkcdmap 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 100755 lustre/tests/llmountcleanup.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/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 100644 lustre/tests/mcreate.c 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 100644 lustre/tests/multifstat.c 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/open_delay.c 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/recovery-cleanup.sh delete mode 100755 lustre/tests/recovery-small.sh delete mode 100644 lustre/tests/rename.pl 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/sanityN.sh delete mode 100755 lustre/tests/snaprun.sh delete mode 100644 lustre/tests/stat.c delete mode 100644 lustre/tests/statmany.c delete mode 100644 lustre/tests/statone.c delete mode 100644 lustre/tests/tbox.sh delete mode 100644 lustre/tests/tchmod.c delete mode 100755 lustre/tests/test.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/wantedi.c 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/automatic-reconnect-sample delete mode 100755 lustre/utils/ha_assist.sh delete mode 100755 lustre/utils/ha_assist2.sh delete mode 100755 lustre/utils/lconf.in delete mode 100644 lustre/utils/lctl.c delete mode 100644 lustre/utils/lfind.c delete mode 100644 lustre/utils/llanalyze delete mode 100644 lustre/utils/llparser.pm delete mode 100755 lustre/utils/lmc delete mode 100644 lustre/utils/lstripe.c delete mode 100755 lustre/utils/mds-failover-sample delete mode 100644 lustre/utils/obd.c delete mode 100644 lustre/utils/obdbarrier.c delete mode 100644 lustre/utils/obdctl.c delete mode 100644 lustre/utils/obdctl.h delete mode 100644 lustre/utils/obdio.c delete mode 100644 lustre/utils/obdiolib.c delete mode 100644 lustre/utils/obdiolib.h delete mode 100644 lustre/utils/obdstat.c 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 34373dd..0000000 --- a/lustre/.cvsignore +++ /dev/null @@ -1,15 +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 -autom4te-2.53.cache 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 61193c7..0000000 --- a/lustre/ChangeLog +++ /dev/null @@ -1,359 +0,0 @@ -TBD - * version v0_5_21 - * bug fixes - - LDLM_DEBUG macro fix, for gcc 3.2 (850) - - failed open()s could cause deadlock; fixed (867, 869) - - stop cancelling OST locks when files are closed (481) - - overlapping XID spaces caused network corruption (851, 853) - - fix unsafe fsfilt counter arithmetic; change to atomic_t - - setattr_raw added, to do single-RPC, server-side setattrs - - lmc/lconf syntax change for OST UUIDs - - fix crashy race condition between ptlrpc_free_req and osc_close - - don't use request in mdc_enqueue if we hit a timeout (889) - - don't set the inode i_size for regular files from the MDS (896) - - handle out of order completion AST (842) - - don't LBUG if a lock request times out after receiving AST (913) - - avoid d_rehash race in ll_find_alias by rehashing inside dcache_lock - - if a bad lock AST arrives, send an error instead of dropping entirely - - return 0 from revalidate2 if ll_intent_lock returns -EINTR (912) - - fix leak in bulk IO when only partially completed (899, 900, 926) - * protocol changes - - READPAGE and SETATTRs which don't take server-side locks get - their own portal - -2003-02-11 Phil Schwan - * version v0_5_20 - * bug fixes - - Fix ldlm_lock_match on the MDS to avoid matching remote locks (592) - - Fix fsfilt_extN_readpage() to read a full page of directory - entries, or fake the remainder if PAGE_SIZE != blocksize (500) - - Avoid extra mdc_getattr() in ll_intent_lock when possible (534, 604) - - Fix imbalanced LOV object allocation and out-of-bound access (469) - - Most intent operations were removed, in favour of a new RPC mode - that does a single RPC to the server and bypasses most of the VFS - - All LDLM resource ID arrays were removed in favour of ldlm_res_id - - Aggressively cancel local locks on DLM servers - - mds_reint_unlink sends EA to the client if it's the last nlink. - client uses that EA to unlink OST objects. - - mds_reint_{rename,unlink,link} were rewritten to take ordered locks - - recursive symlinks were fixed (439) - - fixed NULL deref in DEBUG_REQ - - filter_update_lastobjid no longer calls sync, which annoyed extN - - fixed multi-client small-writes to a single file problem (445) - - fixed mtime updates during file writes (607) - - fixed vector writes on obdfilter causing problems when ENOSPC (670) - - fixed bug in obd_brw_read/write() (under guise of testing 367) - - fixed Linux OST size reporting problem (444, 656) - - OST now updates object mtime with writes or setattr (607, 619) - - client verifies file size before zeroing page past EOF (445) - - OST now writes last allocated objid to disk with allocation (108) - - LOV on echo now works (409) - * protocol changes - - mds_reint_unlink sends a new buffer, with the EA included. this - buffer is only valid if body->valid & OBD_MD_FLEASIZE, which is only - set if a regular file was being unlinked, and it was the last link - - use PtlGet from the target for bulk writes (315) - - OST now updates object mtime with writes or setattr (607, 619) - - LDLM now has a grant-time callback to revalidate locked items, if - necessary (604) - - Many MDS operations were reorganized to combat race conditions - * other changes - - Merge b_intel branch (updated lprocfs code) - now at /proc/fs/lustre - - configure check to avoid gcc version 2.96 20000731-2.96-98) (606) - -2003-01-06 Andreas Dilger - * version v0_5_19 - * bug fixes - - Fully reactivate OST imports after reconnection (512, others) - - Make sure client sees our -ENOTCONN from mds_handle (513 - partial) - - More graceful error handling for truncating on dead OST (515) - - Don't error out unless we're actually accessing dead stripes (474) - - Fix garbage sizes when stripes are missing (410) - - 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) - - lfind did not preserve OST order in output (443) - - symlinks cause hung clients, incorrect data (439) - - stop dereferencing request after dropping refcount (457) - - don't LASSERT(spin_is_locked) on non-SMP (455) - - fixes for many rename() bugs - - fstat didn't correctly synchronize attributes (399) - - server must handle lock cancellation during blocking AST prep (487) - - bulk descriptors were free()d too soon (511) - - fix paths in lconf, which would load incorrect modules (451, 507) - - fix confusing lconf 'host not found' error message (386) - - fix lock order deadlock on OST (O/R i_sem before journal ops, 478) - - fix race condition in mdc_blocking_ast() for inode access (526) - - fix lov_unpackmd() unpacking wrong number of stripes (537) - - fix lov_set_osc_active() marking wrong OSC inactive (440) - - fix bad lstripe lov_unpackmd() assertion (fix layering too) (527) - - fix multiple writes of stripe MD to MDS (358, maybe 519) - - fix lstripe in several ways (kernel side) (527) - - fix request leak in ldlm_cli_enqueue (262) - - incorrect OSC was marked inactive after OST failure - - call mds_fs_cleanup before unmounting filesystem (524) - - fix races between taking ns_lock and ldlm_lock_change_resource - - fix races updating LOV export open file list - - fix lov_enqueue error path, avoid decref-ing bad lock handle - - fix recovery NULL deref in ldlm_cli_cancel_unused - - fix some DLM races by using new hash table for lock handles (419) - - permit the client to specify desired inodes, at replay - - duplicate requests when we queue them for replay reintegration - - fix last_rcvd offset calculation - - sync after each recovered transaction, so we always make progress - - never, not always, ERESTART requests without transnos - - store the lov_desc in the MDS, so we don't depend on getlovinfo to - set it - - skip replay if the MDS says that the client is already connected - - don't check for a recovery-enabled export to match lctl's UUID - - don't INC_USE_COUNT for phantom exports - - don't crash when cleaning up phantom exports (567) - - don't double-finish or set replay data for errored mdc_open requests - - abort requests when they time out, so we don't get old replies - - send/receive replies for AST messages again - - if the client says that it doesn't have the lock, cancel it on the - server - - if we timeout during I/O, don't try to cancel an in-use lock; instead - mark it as destroyed, it will all work out when decref is called - - fix module use counts (22, 581) - * protocol changes - - ASTs now expect a reply (server cancels lock on error reply) - -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 f16f126..0000000 --- a/lustre/Makefile.am +++ /dev/null @@ -1,37 +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 = -else -DIRS24 = extN ptlbd -endif - -if LIBLUSTRE -SUBDIRS = lov obdclass ptlrpc obdecho ldlm osc liblustre utils -else -# NOTE: keep extN before obdclass, mds, and obdfilter. Keep obdclass as early -# as possible, to have the best chance at stopping with "wrong kernel version" -# instead of some related build failure. -SUBDIRS = $(DIRS24) obdclass mds utils ptlrpc ldlm lib obdfilter mdc osc ost -SUBDIRS+= llite obdecho lov cobd tests doc scripts conf -endif - -DIST_SUBDIRS = $(SUBDIRS) -EXTRA_DIST = BUGS FDL Rules include archdep.m4 kernel_patches - -# 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 - rpmbuild -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 d4e5ed7..0000000 --- a/lustre/Rules +++ /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 - -# 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]' | grep -v ".orig" | xargs etags -a - find $(top_srcdir)/../portals/ -name '*.[hc]' | xargs ctags -a - find $(top_srcdir) -name '*.[hc]' | grep -v ".orig" | xargs ctags -a - -AM_CPPFLAGS=-I$(top_builddir)/include diff --git a/lustre/archdep.m4 b/lustre/archdep.m4 deleted file mode 100644 index 2bdd785..0000000 --- a/lustre/archdep.m4 +++ /dev/null @@ -1,127 +0,0 @@ -AC_ARG_WITH(lib, [ --with-lib compile lustre library], host_cpu="lib") - -AC_MSG_CHECKING(if you are running user mode linux for $host_cpu ...) -if test $host_cpu = "lib" ; then - host_cpu="lib" - AC_MSG_RESULT(no building Lustre library) -else -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 -fi - -AC_MSG_CHECKING(setting make flags system architecture: ) -case ${host_cpu} in - lib ) - AC_MSG_RESULT($host_cpu) - KCFLAGS='-g -Wall ' - KCPPFLAGS='-D__arch_lib__ ' - MOD_LINK=elf_i386 -;; - um ) - AC_MSG_RESULT($host_cpu) - KCFLAGS='-g -Wall -pipe -Wno-trigraphs -Wstrict-prototypes -fno-strict-aliasing -fno-common ' - case ${linux25} in - yes ) - 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 -I$(LINUX)/arch/um/kernel/tt/include -O2 -nostdinc -iwithprefix include -DKBUILD_BASENAME=$(MODULE) -DKBUILD_MODNAME=$(MODULE) ' - ;; - * ) - 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 ' - ;; - esac - - MOD_LINK=elf_i386 -;; - i*86 ) - AC_MSG_RESULT($host_cpu) - KCFLAGS='-g -O2 -Wall -Wstrict-prototypes -pipe' - case ${linux25} in - yes ) - KCPPFLAGS='-D__KERNEL__ -DMODULE -march=i686 -I$(LINUX)/include/asm-i386/mach-default -nostdinc -iwithprefix include ' - ;; - * ) - KCPPFLAGS='-D__KERNEL__ -DMODULE ' - ;; - esac - 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='-gstabs -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 - -if test $host_cpu != lib ; then -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 -fi - -CFLAGS="$KCFLAGS $MFLAGS" -ARCHCPPFLAGS="$KCPPFLAGS" diff --git a/lustre/autogen.sh b/lustre/autogen.sh deleted file mode 100644 index 087ff09..0000000 --- a/lustre/autogen.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -find . -type d -name .deps | xargs rm -rf -aclocal && -${AUTOMAKE:-automake} --add-missing && -${AUTOCONF:-autoconf} diff --git a/lustre/cobd/.cvsignore b/lustre/cobd/.cvsignore deleted file mode 100644 index e995588..0000000 --- a/lustre/cobd/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.deps -Makefile -Makefile.in diff --git a/lustre/cobd/Makefile.am b/lustre/cobd/Makefile.am deleted file mode 100644 index 781c6ce..0000000 --- a/lustre/cobd/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2002 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS= - -MODULE = cobd -modulefs_DATA = cobd.o -EXTRA_PROGRAMS = cobd -LINX= - -cobd_SOURCES = cache_obd.c lproc_cache.c $(LINX) - -include $(top_srcdir)/Rules diff --git a/lustre/cobd/cache_obd.c b/lustre/cobd/cache_obd.c deleted file mode 100644 index 67b4e62..0000000 --- a/lustre/cobd/cache_obd.c +++ /dev/null @@ -1,346 +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_COBD - -#include -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -#include -#endif -#include -#include -#include -#include -#include -#include - -static int cobd_attach(struct obd_device *dev, obd_count len, void *data) -{ - struct lprocfs_static_vars lvars; - - lprocfs_init_vars(&lvars); - return lprocfs_obd_attach(dev, lvars.obd_vars); -} - -static int cobd_detach(struct obd_device *dev) -{ - return lprocfs_obd_detach(dev); -} - -static int -cobd_setup (struct obd_device *dev, obd_count len, void *buf) -{ - struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf; - struct cache_obd *cobd = &dev->u.cobd; - struct obd_device *target; - struct obd_device *cache; - struct obd_uuid target_uuid; - struct obd_uuid cache_uuid; - int rc; - - if (data->ioc_inlbuf1 == NULL || - data->ioc_inlbuf2 == NULL) - return (-EINVAL); - - obd_str2uuid(&target_uuid, data->ioc_inlbuf1); - target = class_uuid2obd (&target_uuid); - - obd_str2uuid(&cache_uuid, data->ioc_inlbuf2); - cache = class_uuid2obd (&cache_uuid); - if (target == NULL || - cache == NULL) - return (-EINVAL); - - /* don't bother checking attached/setup; - * obd_connect() should, and it can change underneath us */ - rc = obd_connect (&cobd->cobd_target, target, &target_uuid, NULL, NULL); - if (rc != 0) - return (rc); - - rc = obd_connect (&cobd->cobd_cache, cache, &cache_uuid, NULL, NULL); - if (rc != 0) - goto fail_0; - - return (0); - - fail_0: - obd_disconnect (&cobd->cobd_target); - return (rc); -} - -static int -cobd_cleanup (struct obd_device *dev) -{ - struct cache_obd *cobd = &dev->u.cobd; - int rc; - - if (!list_empty (&dev->obd_exports)) - return (-EBUSY); - - rc = obd_disconnect (&cobd->cobd_cache); - if (rc != 0) - CERROR ("error %d disconnecting cache\n", rc); - - rc = obd_disconnect (&cobd->cobd_target); - if (rc != 0) - CERROR ("error %d disconnecting target\n", rc); - - return (0); -} - -static int -cobd_connect (struct lustre_handle *conn, struct obd_device *obd, - struct obd_uuid *cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - int rc = class_connect (conn, obd, cluuid); - - CERROR ("rc %d\n", rc); - return (rc); -} - -static int -cobd_disconnect (struct lustre_handle *conn) -{ - int rc = class_disconnect (conn); - - CERROR ("rc %d\n", rc); - return (rc); -} - -static int -cobd_get_info(struct lustre_handle *conn, obd_count keylen, - void *key, obd_count *vallen, void **val) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - cobd = &obd->u.cobd; - - /* intercept cache utilisation info? */ - - return (obd_get_info (&cobd->cobd_target, - keylen, key, vallen, val)); -} - -static int -cobd_statfs(struct lustre_handle *conn, struct obd_statfs *osfs) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - cobd = &obd->u.cobd; - return (obd_statfs (&cobd->cobd_target, osfs)); -} - -static int -cobd_getattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - cobd = &obd->u.cobd; - return (obd_getattr (&cobd->cobd_target, oa, lsm)); -} - -static int -cobd_open(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm, struct obd_trans_info *oti) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - cobd = &obd->u.cobd; - return (obd_open (&cobd->cobd_target, oa, lsm, oti)); -} - -static int -cobd_close(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm, struct obd_trans_info *oti) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - cobd = &obd->u.cobd; - return (obd_close (&cobd->cobd_target, oa, lsm, oti)); -} - -static int -cobd_preprw(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_remote *nb, - struct niobuf_local *res, void **desc_private, - struct obd_trans_info *oti) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - if ((cmd & OBD_BRW_WRITE) != 0) - return -EOPNOTSUPP; - - cobd = &obd->u.cobd; - return (obd_preprw (cmd, &cobd->cobd_target, - objcount, obj, - niocount, nb, - res, desc_private, oti)); -} - -static int -cobd_commitrw(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_local *local, - void *desc_private, struct obd_trans_info *oti) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - if ((cmd & OBD_BRW_WRITE) != 0) - return -EOPNOTSUPP; - - cobd = &obd->u.cobd; - return (obd_commitrw (cmd, &cobd->cobd_target, - objcount, obj, - niocount, local, - desc_private, oti)); -} - -static inline int -cobd_brw(int cmd, struct lustre_handle *conn, - struct lov_stripe_md *lsm, obd_count oa_bufs, - struct brw_page *pga, struct obd_brw_set *set, - struct obd_trans_info *oti) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - if ((cmd & OBD_BRW_WRITE) != 0) - return -EOPNOTSUPP; - - cobd = &obd->u.cobd; - return (obd_brw (cmd, &cobd->cobd_target, - lsm, oa_bufs, pga, set, oti)); -} - -static int -cobd_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len, - void *karg, void *uarg) -{ - struct obd_device *obd = class_conn2obd(conn); - struct cache_obd *cobd; - - if (obd == NULL) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - /* intercept? */ - - cobd = &obd->u.cobd; - return (obd_iocontrol (cmd, &cobd->cobd_target, len, karg, uarg)); -} - -static struct obd_ops cobd_ops = { - o_owner: THIS_MODULE, - o_attach: cobd_attach, - o_detach: cobd_detach, - - o_setup: cobd_setup, - o_cleanup: cobd_cleanup, - - o_connect: cobd_connect, - o_disconnect: cobd_disconnect, - - o_get_info: cobd_get_info, - o_statfs: cobd_statfs, - - o_getattr: cobd_getattr, - o_open: cobd_open, - o_close: cobd_close, - o_preprw: cobd_preprw, - o_commitrw: cobd_commitrw, - o_brw: cobd_brw, - o_iocontrol: cobd_iocontrol, -}; - -static int __init cobd_init(void) -{ - struct lprocfs_static_vars lvars; - ENTRY; - - printk(KERN_INFO "Lustre Caching OBD driver; info@clusterfs.com\n"); - - lprocfs_init_vars(&lvars); - RETURN(class_register_type(&cobd_ops, lvars.module_vars, - OBD_CACHE_DEVICENAME)); -} - -static void __exit cobd_exit(void) -{ - class_unregister_type(OBD_CACHE_DEVICENAME); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Caching OBD driver"); -MODULE_LICENSE("GPL"); - -module_init(cobd_init); -module_exit(cobd_exit); diff --git a/lustre/cobd/lproc_cache.c b/lustre/cobd/lproc_cache.c deleted file mode 100644 index 7e5c267..0000000 --- a/lustre/cobd/lproc_cache.c +++ /dev/null @@ -1,89 +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 - -#ifndef LPROCFS -struct lprocfs_vars lprocfs_obd_vars[] = { {0} }; -struct lprocfs_vars lprocfs_module_vars[] = { {0} }; -#else -/* Common STATUS namespace */ -static int rd_target(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device *dev = (struct obd_device*)data; - struct lustre_handle *conn; - struct obd_export *exp; - int rc; - - LASSERT(dev != NULL); - conn = &dev->u.cobd.cobd_target; - - if ((dev->obd_flags & OBD_SET_UP) == 0) - rc = snprintf (page, count, "not set up\n"); - else { - exp = class_conn2export (conn); - LASSERT(exp != NULL); - rc = snprintf(page, count, "%s\n", - exp->exp_obd->obd_uuid.uuid); - } - return (rc); -} - -static int rd_cache(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device *dev = (struct obd_device*)data; - struct lustre_handle *conn; - struct obd_export *exp; - int rc; - - LASSERT(dev != NULL); - conn = &dev->u.cobd.cobd_cache; - - if ((dev->obd_flags & OBD_SET_UP) == 0) - rc = snprintf (page, count, "not set up\n"); - else { - exp = class_conn2export (conn); - LASSERT (exp != NULL); - rc = snprintf(page, count, "%s\n", - exp->exp_obd->obd_uuid.uuid); - } - return (rc); -} - -struct lprocfs_vars lprocfs_obd_vars[] = { - { "uuid", lprocfs_rd_uuid, 0, 0 }, - { "target_uuid", rd_target, 0, 0 }, - { "cache_uuid", rd_cache, 0, 0 }, - { 0 } -}; - -struct lprocfs_vars lprocfs_module_vars[] = { - { "num_refs", lprocfs_rd_numrefs, 0, 0 }, - { 0 } -}; -#endif /* LPROCFS */ - -LPROCFS_INIT_VARS(lprocfs_module_vars, lprocfs_obd_vars) diff --git a/lustre/conf/.cvsignore b/lustre/conf/.cvsignore deleted file mode 100644 index 282522d..0000000 --- a/lustre/conf/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile -Makefile.in diff --git a/lustre/conf/Makefile.am b/lustre/conf/Makefile.am deleted file mode 100644 index a205d10..0000000 --- a/lustre/conf/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 - -EXTRA_DIST = lustre.dtd lustre.schema slapd-lustre.conf lustre2ldif.xsl top.ldif -ldapconfdir = $(sysconfdir)/openldap -ldapschemadir = $(sysconfdir)/openldap/schema -ldapconf_SCRIPTS = slapd-lustre.conf -ldapschema_SCRIPTS = lustre.schema -pkglibdir = '${exec_prefix}/usr/lib/$(PACKAGE)' -pkglib_DATA = top.ldif lustre2ldif.xsl - -include $(top_srcdir)/Rules - diff --git a/lustre/conf/lustre.dtd b/lustre/conf/lustre.dtd deleted file mode 100644 index 8d575a61..0000000 --- a/lustre/conf/lustre.dtd +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lustre/conf/lustre2ldif.xsl b/lustre/conf/lustre2ldif.xsl deleted file mode 100644 index f3c1364..0000000 --- a/lustre/conf/lustre2ldif.xsl +++ /dev/null @@ -1,233 +0,0 @@ - - - - -fs=lustre -config=,fs=lustre - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lustre/conf/slapd-lustre.conf b/lustre/conf/slapd-lustre.conf deleted file mode 100644 index de89c76..0000000 --- a/lustre/conf/slapd-lustre.conf +++ /dev/null @@ -1,12 +0,0 @@ -####################################################################### -# lustre ldap config database -# $Id: slapd-lustre.conf,v 1.2 2003/01/06 22:17:53 adilger Exp $ -####################################################################### - -database ldbm -suffix "fs=lustre" -rootdn "cn=Manager,fs=lustre" -include /etc/openldap/schema/lustre.schema -rootpw secret -directory /var/lib/ldap/lustre -index objectClass eq, uuid eq diff --git a/lustre/conf/top.ldif b/lustre/conf/top.ldif deleted file mode 100644 index d0cfdac..0000000 --- a/lustre/conf/top.ldif +++ /dev/null @@ -1,4 +0,0 @@ -dn: fs=lustre -fs:lustre -objectClass: lustre -lustreDesc: Lustre Config diff --git a/lustre/configure.in b/lustre/configure.in deleted file mode 100644 index 6384d30..0000000 --- a/lustre/configure.in +++ /dev/null @@ -1,185 +0,0 @@ -AC_INIT -AC_CANONICAL_SYSTEM - -# Copyright (C) 2001-2003 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_MSG_CHECKING(for buggy compiler) -CC_VERSION=`$CC -v 2>&1 | grep "^gcc version"` -bad_cc() { - echo - echo " '$CC_VERSION'" - echo " has been known to generate bad code, " - echo " please get an updated compiler." - AC_MSG_ERROR(sorry) -} -TMP_VERSION=`echo $CC_VERSION | cut -c 1-16` -if test "$TMP_VERSION" = "gcc version 2.95"; then - bad_cc -fi -case "$CC_VERSION" in - # ost_pack_niobuf putting 64bit NTOH temporaries on the stack - # without "sub $0xc,%esp" to protect the stack from being - # stomped on by interrupts (bug 606) - "gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-98)") - bad_cc - ;; - *) - AC_MSG_RESULT(no known problems) - ;; -esac - -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) - -# XXX this should be a runtime option -AC_ARG_ENABLE(ost_recovery, [ --enable-ost-recovery: enable support for ost recovery],, - enable_ost_recovery="yes") -if test "$enable_ost_recovery" = "yes" ; then - ENABLE_OST_RECOVERY="-DOST_RECOVERY=1" -else - HAVE_LIBREADLINE="" -fi -AC_SUBST(ENABLE_OST_RECOVERY) - - -# 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) - -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) - -sinclude(archdep.m4) - - -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=$portalsdir_def],, enable_portalsdir=$portalsdir_def) -PORTALS=$enable_portalsdir - -if test $PORTALS = $portalsdir_def; then - PORTALSLOC='../portals' -else - PORTALSLOC=$PORTALS -fi - -AC_SUBST(PORTALS) -AC_SUBST(PORTALSLOC) - -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) - -AM_CONDITIONAL(LIBLUSTRE, test x$host_cpu = xlib) -AC_MSG_CHECKING(if you are building lib lustre) -if test "$host_cpu" = "lib"; then - AC_MSG_RESULT(yes) - libdir='${exec_prefix}/lib/lustre' -else - AC_MSG_RESULT(no) -fi - -if test $host_cpu != "lib" ; then -KINCFLAGS='-I$(top_srcdir)/include -I$(PORTALS)/include -I$(LINUX)/include' -else -KINCFLAGS='-I$(top_srcdir)/include -I$(PORTALS)/include' -fi -CPPFLAGS="$KINCFLAGS $ARCHCPPFLAGS" - -if test $host_cpu != "lib" ; then -AC_MSG_CHECKING(if make dep has been run in kernel source (host $host_cpu) ) -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) - -fi -# 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 \ - liblustre/Makefile \ - lov/Makefile osc/Makefile mdc/Makefile mds/Makefile ost/Makefile \ - cobd/Makefile ptlbd/Makefile conf/Makefile \ - utils/Makefile utils/lconf tests/Makefile obdfilter/Makefile \ - obdclass/Makefile llite/Makefile doc/Makefile scripts/Makefile \ - scripts/lustre.spec extN/Makefile, chmod +x utils/lconf) 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 3bfecbd..0000000 --- a/lustre/doc/lconf.lyx +++ /dev/null @@ -1,145 +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 Description - -lconf Lustre filesystem 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 Specify a specific node to configure. - By default, lconf will search for nodes with the local hostname and 'localhost'. - When -\emph on - --node -\emph default - is used, only -\emph on -node_name -\emph default - 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 -\emph on ---node -\emph default - 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 -\emph on ---node -\emph default -, 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 - ---reformat Reformat all the devices -\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 - - -\size small -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. -\the_end diff --git a/lustre/doc/lctl.lyx b/lustre/doc/lctl.lyx deleted file mode 100644 index 33b40b2..0000000 --- a/lustre/doc/lctl.lyx +++ /dev/null @@ -1,662 +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 Description - -lctl Low level Lustre filesystem 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 -\size small -device -\family default -\size default - and -\family typewriter -\size small -attach -\family default -\size default -, -\family typewriter -\size small -detach -\family default -\size default - and -\family typewriter -\size small -setup -\family default -\size default -, -\family typewriter -\size small -cleanup -\family default -\size default - and -\family typewriter -\size small -connect -\family default -\size default -, -\family typewriter -\size small -disconnect -\family default -\size default - and -\family typewriter -\size small -help -\family default -\size default -, and -\family typewriter -\size small -quit -\family default -\size default -. - To get a complete listing of available commands, type -\family typewriter -\size small -help -\family default -\size default - at the lctl prompt. - To get basic help on the meaning and syntax of a command, type -\family typewriter -\size small -help command -\family default -\size default -. - Command completion is activated with the -\family typewriter -\size small -TAB -\family default -\size 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 device -\emph on -. - -\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 positive integer indicating how many - threads should be started. - The -\emph on -devno -\emph default -option is used as above. -\layout LyX-Code - -\layout LyX-Code - -\layout Description - -Network\SpecialChar ~ -Configuration -\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 -\emph on -id -\emph default - given by the hostname/port combination, or the elan -\emph on -id -\emph default -. -\layout Description - -disconnect\SpecialChar ~ - Disconnect from a remote -\emph on -nid -\emph default -. -\layout Description - -mynid\SpecialChar ~ -[nid] Informs the socknal of the local -\emph on -nid -\emph default -. - 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. -\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 -\emph on -receive -\emph default - buffer size; if the size is omitted, the default size for the buffer is - printed. -\layout Description - -send_mem\SpecialChar ~ -[size] Set send buffer size for the socket; if size is omitted, - the default size for the buffer is printed. -\layout Description - -nagle\SpecialChar ~ -[on/off] Enable/disable nagle; omitting the argument 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 ~ -Configuration -\begin_deeper -\layout Description - -attach\SpecialChar ~ -type\SpecialChar ~ -[name\SpecialChar ~ -[uuid]] -\shape italic -\emph on -Attach -\shape default -\emph default - a type to the current device (which you need to set using the -\family typewriter -\size small -device -\family default -\size 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 UUID's. -\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 until the lctl command has - ensured that the MDS and OSC services are available. - This is to avoid mount failures in a rebooting cluster. -\layout Description - -close -\emph on - -\layout Description - -getattr\SpecialChar ~ - Get attributes for an OST object -\emph on - -\emph default - . -\layout Description - -setattr\SpecialChar ~ -\SpecialChar ~ - Set mode attribute for OST object -\emph on - -\emph default -. -\layout Description - -create\SpecialChar ~ -[num\SpecialChar ~ -[mode\SpecialChar ~ -[verbose]]] Create the specified number -\emph on - -\emph default - of OST objects with the given -\emph on - -\emph default -. -\layout Description - -destroy\SpecialChar ~ - Destroy an OST object. -\layout Description - -test_getattr\SpecialChar ~ -\SpecialChar ~ -[verbose\SpecialChar ~ -[[t]objid]] Do -\emph on - -\emph default - -\emph on -getattrs -\emph default - on OST object -\emph on - -\emph default - ( -\emph on -objectid -\emph default -+1 on each thread). -\layout Description - -test_brw\SpecialChar ~ -[t]\SpecialChar ~ -[write\SpecialChar ~ -[verbose\SpecialChar ~ -[npages\SpecialChar ~ -[[t]objid]]]] Do -\emph on - -\emph default - bulk -\emph on -read -\emph default -/ -\emph on -writes -\emph default - on OST object -\emph on - -\emph default - ( -\emph on - -\emph default - 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 -\emph on -fileusage -\emph default -. -\layout Description - -debug_file\SpecialChar ~ -\SpecialChar ~ -[output]\SpecialChar ~ -[raw] Read debug buffer from input and dump to - -\emph on -outputusage -\emph default -. -\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; -\emph on -help -\emph default - 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 - - -\size small -# lctl -\newline -lctl > newdev -\newline -lctl > attach obdfilter OBDDEV OBDUUID -\size default - -\newline - -\layout Description - -connect -\layout LyX-Code - - -\size small -lctl > name2dev OSCDEV -\newline -2 -\newline -lctl > device 2 -\newline -lctl > connect -\size default - -\newline - -\layout Description - -getattr -\layout LyX-Code - - -\size small -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) -\newline - -\layout Description - -setup -\emph on - -\layout LyX-Code - - -\size small -lctl > setup /dev/loop0 extN -\newline -lctl > quit -\size default - -\newline - -\layout LyX-Code - -\layout Subsection - -BUGS -\layout Standard - -None are known. -\the_end diff --git a/lustre/doc/lmc.lyx b/lustre/doc/lmc.lyx deleted file mode 100644 index 2cbcdc0..0000000 --- a/lustre/doc/lmc.lyx +++ /dev/null @@ -1,444 +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 Description - -lmc Lustre configuration maker. -\layout Subsection - -SYNOPSIS -\layout Standard - - -\series bold -lmc [options] --add [args] -\layout Standard - - -\series bold -lmc [options] --remove [args] -- [NOT IMPLEMENTED] -\layout Standard - - -\series bold -lmc [options] --convert [args] -- [NOT IMPLEMENTED] -\layout Subsection - -DESCRIPTION -\layout Standard - -At present -\series bold -\emph on -lmc -\series default -\emph default -, when invoked, adds configuration data to the config file. - In future, -\series bold -\emph on -lmc -\series default -\emph default - will also be able to remove configuration data or convert its format. - A Lustre cluster consists of several components - MDS's, mount-points, - OSTs, LOVs and whatever those reference (e.g nets and profiles). - A single configuration file would be generated for the complete cluster. - In the -\series bold -\emph on -lmc -\series default -\emph default - command line interface, each of these components is associated with an - -\emph on -objecttype -\emph default -. - -\layout Standard - -The -\emph on -objecttype -\emph default - refers to a collection of related configuration entities and can be one - of -\series bold -net -\series default -, -\series bold - MDS -\series default -, -\series bold - LOV -\series default -, -\series bold - OST -\series default -, -\series bold - mtpt -\series default -, -\series bold - route -\series default -, -\series bold - -\series default -or -\series bold - echo_client. - -\series default -We describe the arguments required for the addition of each -\emph on -objecttype -\emph default -. - -\layout Standard - -To generate configuration data associated with systems in a Lustre cluster: -\layout Description - - -\emph on -- -\emph default --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'' This will create a new node with the given name if not - already present. - This is also used to specify a specific node for other elements. -\layout Description - ---nettype\SpecialChar ~ - This can be -\series bold -tcp, elan, gm. -\layout Description - ---nid\SpecialChar ~ -nid The network -\emph on -id -\emph default -, e.g. - ElanID or IP address as used by Portals. - If -\emph on -nid -\emph default - is '*', then the local address of the interface with specified -\series bold -nettype -\series default -is will be substituted when the node is configured with lconf. - An -\emph on -nid -\emph default - of -\emph on -'*' -\emph default - should be used only for the generic -\emph on -client -\emph default - configuration. -\layout Description - ---router Optional flag to mark this node as a router -\layout Description - ---profile\SpecialChar ~ -[not\SpecialChar ~ -implemented] Optional flag to mark this node as a profile node. - This would be very useful to configure several client nodes in large clusters. - It will allow user to define -\series bold -profiles -\series default - for the various client configurations, and then load the correct profile - on the client nodes using lconf. - -\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 - ---dev\SpecialChar ~ - Path of device on local system. - If the is a file, then a loop device is created and used as the block device. -\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 -\emph on ---node -\emph default - argument, and it must not be a profile node. -\end_deeper -\layout Description - ---add\SpecialChar ~ -lov Creates an LOV with the specified parameters. - The -\emph on -mds_name -\emph default - must already exist in the descriptor. -\begin_deeper -\layout Description - ---lov\SpecialChar ~ - -\layout Description - ---mds\SpecialChar ~ - -\layout Description - ---stripe_sz\SpecialChar ~ - -\layout Description - ---stripe_cnt\SpecialChar ~ - -\layout Description - ---stripe_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 - ---obd\SpecialChar ~ - Assign a name to the OBD device. -\layout Description - ---node\SpecialChar ~ - Node on which the OST service is run, can not be a profile - node. -\layout Description - ---dev\SpecialChar ~ - Path of device on local system. - If this is a file, then a loop device is created and used as the block - device. -\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 -\emph on -OBD_nodename_UUID -\emph default -. -\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 -\emph on -mtpt -\emph default -. -\layout Description - ---path\SpecialChar ~ -/mnt/path\SpecialChar ~ - -\layout Description - ---mds\SpecialChar ~ -mds_name -\layout Description - ---obd\SpecialChar ~ -obd_name\SpecialChar ~ -|\SpecialChar ~ ---lov\SpecialChar ~ -lov_name -\end_deeper -\layout Description - ---add\SpecialChar ~ -route Creates a static route through a gateway to a specific -\emph on -nid -\emph default - or a range of -\emph on -nid -\emph default -'s. -\begin_deeper -\layout Description - ---node\SpecialChar ~ -node Node or profile node to add the route to. -\layout Description - ---gw\SpecialChar ~ -nid The -\emph on -nid -\emph default - of the gateway (must be a local interface or a peer). -\layout Description - ---tgt\SpecialChar ~ -nid For a specific route, this is the target -\emph on -nid. -\layout Description - ---lo\SpecialChar ~ -nid For a range route, this is the lo value -\emph on -nid. -\layout Description - ---hi\SpecialChar ~ -nid For a range route, this is the hi value -\emph on -nid. -\end_deeper -\layout Description - ---add\SpecialChar ~ -echo-client Used for testing purpose only -\begin_deeper -\layout Description - ---node\SpecialChar ~ -node -\emph on - -\layout Description - ---obd\SpecialChar ~ -obd_name -\end_deeper -\layout List -\labelwidthstring 00.00.0000 - - -\series bold -Options -\layout Description - ---output\SpecialChar ~ -filename Send output to the file. - If the file exists, it will be overwritten. -\layout Description - ---merge\SpecialChar ~ -filename -\emph on - -\emph default -Add the new element to an existing file. - -\layout Subsection - -EXAMPLES -\layout Standard - -Real life examples are given in the Lustre-conf manual page. -\layout Subsection - -BUGS -\layout Standard - -None are known. -\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 d1de59b..0000000 --- a/lustre/extN/Makefile.am +++ /dev/null @@ -1,144 +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 = 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 ext3-2.4-ino_t.diff -EXTNP+= ext3-2.4.18-ino_sb_macro.diff extN-misc-fixup.diff extN-noread.diff -EXTNP+= extN-wantedi.diff extN-san.diff extN-2.4.18-ino_sb_fixup.diff -#EXTNP+= extN-iget-debug.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) \ - ext3-largefile.diff extN-2.4.18-exports.diff \ - ext3-use-after-free.diff ext3-unmount_sync.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 \ - list='$(EXTNP)'; \ - grep -q "err = extN_mark_inode_dirty" $(extN_orig)/namei.c || \ - list="ext3-use-after-free.diff $$list"; \ - sed '/i_version/q' $(extN_orig)/namei.c | tail -2 | \ - grep -q extN_mark_inode_dirty && list="$(EXTN_FIXES) $$list"; \ - grep -q "if (do_sync_supers)" $(extN_orig)/super.c && \ - list="ext3-unmount_sync.diff $$list"; \ - grep -q "ext3_journal_start(inode, 2)" $(extN_orig)/inode.c || \ - list="ext3-largefile.diff $$list"; \ - grep -q "EXPORT_SYMBOL(extN_bread)" $(extN_orig)/super.c || \ - list="$$list extN-2.4.18-exports.diff"; \ - for p in $$list; do \ - echo "applying patch $$p"; \ - sed $(SUB) $(srcdir)/$$p | \ - (cd $(top_builddir) && patch -p1) || exit $$?; \ - done; \ - 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-ino_t.diff b/lustre/extN/ext3-2.4-ino_t.diff deleted file mode 100644 index ce1bd88..0000000 --- a/lustre/extN/ext3-2.4-ino_t.diff +++ /dev/null @@ -1,138 +0,0 @@ ---- linux/fs/ext3/ialloc.c.orig Sat Oct 19 11:42:23 2002 -+++ linux/fs/ext3/ialloc.c Sat Jan 4 12:14:18 2003 -@@ -64,8 +64,8 @@ static int read_inode_bitmap (struct sup - if (!bh) { - ext3_error (sb, "read_inode_bitmap", - "Cannot read inode bitmap - " -- "block_group = %lu, inode_bitmap = %lu", -- block_group, (unsigned long) gdp->bg_inode_bitmap); -+ "block_group = %lu, inode_bitmap = %u", -+ block_group, gdp->bg_inode_bitmap); - retval = -EIO; - } - /* -@@ -531,19 +532,19 @@ out: - } - - /* Verify that we are loading a valid orphan from disk */ --struct inode *ext3_orphan_get (struct super_block * sb, ino_t ino) -+struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino) - { -- ino_t max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count); -+ unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count); - unsigned long block_group; - int bit; - int bitmap_nr; - struct buffer_head *bh; - struct inode *inode = NULL; -- -+ - /* Error cases - e2fsck has already cleaned up for us */ - if (ino > max_ino) { - ext3_warning(sb, __FUNCTION__, -- "bad orphan ino %ld! e2fsck was run?\n", ino); -+ "bad orphan ino %lu! e2fsck was run?\n", ino); - return NULL; - } - -@@ -552,7 +553,7 @@ struct inode *ext3_orphan_get (struct su - if ((bitmap_nr = load_inode_bitmap(sb, block_group)) < 0 || - !(bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr])) { - ext3_warning(sb, __FUNCTION__, -- "inode bitmap error for orphan %ld\n", ino); -+ "inode bitmap error for orphan %lu\n", ino); - return NULL; - } - -@@ -563,7 +564,7 @@ struct inode *ext3_orphan_get (struct su - if (!ext3_test_bit(bit, bh->b_data) || !(inode = iget(sb, ino)) || - is_bad_inode(inode) || NEXT_ORPHAN(inode) > max_ino) { - ext3_warning(sb, __FUNCTION__, -- "bad orphan inode %ld! e2fsck was run?\n", ino); -+ "bad orphan inode %lu! e2fsck was run?\n", ino); - printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%ld) = %d\n", - bit, bh->b_blocknr, ext3_test_bit(bit, bh->b_data)); - printk(KERN_NOTICE "inode=%p\n", inode); -@@ -570,9 +571,9 @@ struct inode *ext3_orphan_get (struct su - if (inode) { - printk(KERN_NOTICE "is_bad_inode(inode)=%d\n", - is_bad_inode(inode)); -- printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%d\n", -+ printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", - NEXT_ORPHAN(inode)); -- printk(KERN_NOTICE "max_ino=%ld\n", max_ino); -+ printk(KERN_NOTICE "max_ino=%lu\n", max_ino); - } - /* Avoid freeing blocks if we got a bad deleted inode */ - if (inode && inode->i_nlink == 0) ---- linux/fs/ext3/namei.c.orig Sat Oct 19 11:42:45 2002 -+++ linux/fs/ext3/namei.c Sat Jan 4 12:13:27 2003 -@@ -716,10 +716,10 @@ int ext3_orphan_del(handle_t *handle, st - { - struct list_head *prev; - struct ext3_sb_info *sbi; -- ino_t ino_next; -+ unsigned long ino_next; - struct ext3_iloc iloc; - int err = 0; -- -+ - lock_super(inode->i_sb); - if (list_empty(&inode->u.ext3_i.i_orphan)) { - unlock_super(inode->i_sb); -@@ -730,7 +730,7 @@ int ext3_orphan_del(handle_t *handle, st - prev = inode->u.ext3_i.i_orphan.prev; - sbi = EXT3_SB(inode->i_sb); - -- jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino); -+ jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino); - - list_del(&inode->u.ext3_i.i_orphan); - INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); -@@ -741,13 +741,13 @@ int ext3_orphan_del(handle_t *handle, st - * list in memory. */ - if (!handle) - goto out; -- -+ - err = ext3_reserve_inode_write(handle, inode, &iloc); - if (err) - goto out_err; - - if (prev == &sbi->s_orphan) { -- jbd_debug(4, "superblock will point to %ld\n", ino_next); -+ jbd_debug(4, "superblock will point to %lu\n", ino_next); - BUFFER_TRACE(sbi->s_sbh, "get_write_access"); - err = ext3_journal_get_write_access(handle, sbi->s_sbh); - if (err) -@@ -758,8 +758,8 @@ int ext3_orphan_del(handle_t *handle, st - struct ext3_iloc iloc2; - struct inode *i_prev = - list_entry(prev, struct inode, u.ext3_i.i_orphan); -- -- jbd_debug(4, "orphan inode %ld will point to %ld\n", -+ -+ jbd_debug(4, "orphan inode %lu will point to %lu\n", - i_prev->i_ino, ino_next); - err = ext3_reserve_inode_write(handle, i_prev, &iloc2); - if (err) -@@ -774,7 +774,7 @@ int ext3_orphan_del(handle_t *handle, st - if (err) - goto out_brelse; - --out_err: -+out_err: - ext3_std_error(inode->i_sb, err); - out: - unlock_super(inode->i_sb); ---- linux/include/linux/ext3_fs.h.orig Thu Jan 2 16:10:24 2003 -+++ linux/include/linux/ext3_fs.h Sat Jan 4 12:25:41 2003 -@@ -622,7 +622,7 @@ extern int ext3_sync_file (struct file * - /* ialloc.c */ - extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int); - extern void ext3_free_inode (handle_t *, struct inode *); --extern struct inode * ext3_orphan_get (struct super_block *, ino_t); -+extern struct inode * ext3_orphan_get (struct super_block *, unsigned long); - extern unsigned long ext3_count_free_inodes (struct super_block *); - extern void ext3_check_inodes_bitmap (struct super_block *); - extern unsigned long ext3_count_free (struct buffer_head *, unsigned); diff --git a/lustre/extN/ext3-2.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 cc47588..0000000 --- a/lustre/extN/ext3-2.4.18-ino_sb_macro.diff +++ /dev/null @@ -1,1554 +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; - unsigned long ino_next; - struct ext3_iloc iloc; - int err = 0; - - lock_super(inode->i_sb); -- if (list_empty(&inode->u.ext3_i.i_orphan)) { -+ if (list_empty(&ei->i_orphan)) { - unlock_super(inode->i_sb); - return 0; - } - - ino_next = NEXT_ORPHAN(inode); -- prev = inode->u.ext3_i.i_orphan.prev; -+ prev = ei->i_orphan.prev; - sbi = EXT3_SB(inode->i_sb); - - jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino); - -- list_del(&inode->u.ext3_i.i_orphan); -- INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); -+ list_del_init(&ei->i_orphan); - - /* If we're on an error path, we may not have a valid - * transaction handle with which to update the orphan list on -@@ -1520,8 +1520,7 @@ int ext3_orphan_del(handle_t *handle, st - err = ext3_journal_dirty_metadata(handle, sbi->s_sbh); - } else { - struct ext3_iloc iloc2; -- struct inode *i_prev = -- list_entry(prev, struct inode, u.ext3_i.i_orphan); -+ struct inode *i_prev = orphan_list_entry(prev); - - jbd_debug(4, "orphan inode %lu will point to %lu\n", - i_prev->i_ino, ino_next); -@@ -1695,10 +1695,10 @@ static int ext3_symlink (struct inode * - goto out_no_entry; - } else { - inode->i_op = &ext3_fast_symlink_inode_operations; -- memcpy((char*)&inode->u.ext3_i.i_data,symname,l); -+ memcpy((char*)&EXT3_I(inode)->i_data,symname,l); - inode->i_size = l-1; - } -- inode->u.ext3_i.i_disksize = inode->i_size; -+ EXT3_I(inode)->i_disksize = inode->i_size; - err = ext3_add_nondir(handle, dentry, inode); - ext3_mark_inode_dirty(handle, inode); - out_stop: ---- ./fs/ext3/super.c.orig Fri Apr 12 10:27:49 2002 -+++ ./fs/ext3/super.c Tue May 7 16:05:44 2002 -@@ -121,7 +121,7 @@ static int ext3_error_behaviour(struct s - /* If no overrides were specified on the mount, then fall back - * to the default behaviour set in the filesystem's superblock - * on disk. */ -- switch (le16_to_cpu(sb->u.ext3_sb.s_es->s_errors)) { -+ switch (le16_to_cpu(EXT3_SB(sb)->s_es->s_errors)) { - case EXT3_ERRORS_PANIC: - return EXT3_ERRORS_PANIC; - case EXT3_ERRORS_RO: -@@ -269,9 +269,9 @@ void ext3_abort (struct super_block * sb - return; - - printk (KERN_CRIT "Remounting filesystem read-only\n"); -- sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS; -+ EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS; - sb->s_flags |= MS_RDONLY; -- sb->u.ext3_sb.s_mount_opt |= EXT3_MOUNT_ABORT; -+ EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT; - journal_abort(EXT3_SB(sb)->s_journal, -EIO); - } - -@@ -377,8 +377,6 @@ static int ext3_blkdev_remove(struct ext3 - return ret; - } - --#define orphan_list_entry(l) list_entry((l), struct inode, u.ext3_i.i_orphan) -- - static void dump_orphan_list(struct super_block *sb, struct ext3_sb_info *sbi) - { - struct list_head *l; -@@ -818,7 +818,7 @@ static void ext3_orphan_cleanup (struct - sb->s_flags &= ~MS_RDONLY; - } - -- if (sb->u.ext3_sb.s_mount_state & EXT3_ERROR_FS) { -+ if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) { - if (es->s_last_orphan) - jbd_debug(1, "Errors on filesystem, " - "clearing orphan list.\n"); -@@ -1463,12 +1463,14 @@ static void ext3_commit_super (struct su - struct ext3_super_block * es, - int sync) - { -+ struct buffer_head *sbh = EXT3_SB(sb)->s_sbh; -+ - es->s_wtime = cpu_to_le32(CURRENT_TIME); -- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "marking dirty"); -- mark_buffer_dirty(sb->u.ext3_sb.s_sbh); -+ BUFFER_TRACE(sbh, "marking dirty"); -+ mark_buffer_dirty(sbh); - if (sync) { -- ll_rw_block(WRITE, 1, &sb->u.ext3_sb.s_sbh); -- wait_on_buffer(sb->u.ext3_sb.s_sbh); -+ ll_rw_block(WRITE, 1, &sbh); -+ wait_on_buffer(sbh); - } - } - -@@ -1519,7 +1521,7 @@ static void ext3_clear_journal_err(struc - ext3_warning(sb, __FUNCTION__, "Marking fs in need of " - "filesystem check."); - -- sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS; -+ EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS; - es->s_state |= cpu_to_le16(EXT3_ERROR_FS); - ext3_commit_super (sb, es, 1); - ---- ./fs/ext3/symlink.c.orig Fri Apr 12 10:27:49 2002 -+++ ./fs/ext3/symlink.c Tue May 7 15:25:39 2002 -@@ -23,13 +23,13 @@ - - static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen) - { -- char *s = (char *)dentry->d_inode->u.ext3_i.i_data; -- return vfs_readlink(dentry, buffer, buflen, s); -+ struct ext3_inode_info *ei = EXT3_I(dentry->d_inode); -+ return vfs_readlink(dentry, buffer, buflen, (char *)ei->i_data); - } - - static int ext3_follow_link(struct dentry *dentry, struct nameidata *nd) - { -- char *s = (char *)dentry->d_inode->u.ext3_i.i_data; -- return vfs_follow_link(nd, s); -+ struct ext3_inode_info *ei = EXT3_I(dentry->d_inode); -+ return vfs_follow_link(nd, (char*)ei->i_data); - } - ---- ./include/linux/ext3_fs.h.orig Tue Apr 16 14:27:25 2002 -+++ ./include/linux/ext3_fs.h Tue May 7 16:47:36 2002 -@@ -84,22 +84,25 @@ - #define EXT3_MIN_BLOCK_SIZE 1024 - #define EXT3_MAX_BLOCK_SIZE 4096 - #define EXT3_MIN_BLOCK_LOG_SIZE 10 -+ - #ifdef __KERNEL__ --# define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) --#else --# define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) --#endif --#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) --#ifdef __KERNEL__ --# define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) --#else --# define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) --#endif --#ifdef __KERNEL__ --#define EXT3_ADDR_PER_BLOCK_BITS(s) ((s)->u.ext3_sb.s_addr_per_block_bits) --#define EXT3_INODE_SIZE(s) ((s)->u.ext3_sb.s_inode_size) --#define EXT3_FIRST_INO(s) ((s)->u.ext3_sb.s_first_ino) -+#define EXT3_SB(sb) (&((sb)->u.ext3_sb)) -+#define EXT3_I(inode) (&((inode)->u.ext3_i)) -+ -+#define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) -+#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) -+#define EXT3_ADDR_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_addr_per_block_bits) -+#define EXT3_INODE_SIZE(s) (EXT3_SB(s)->s_inode_size) -+#define EXT3_FIRST_INO(s) (EXT3_SB(s)->s_first_ino) - #else -+ -+/* Assume that user mode programs are passing in an ext3fs superblock, not -+ * a kernel struct super_block. This will allow us to call the feature-test -+ * macros from user land. */ -+#define EXT3_SB(sb) (sb) -+ -+#define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) -+#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) - #define EXT3_INODE_SIZE(s) (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ? \ - EXT3_GOOD_OLD_INODE_SIZE : \ - (s)->s_inode_size) -@@ -108,6 +110,7 @@ - EXT3_GOOD_OLD_FIRST_INO : \ - (s)->s_first_ino) - #endif -+#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) - - /* - * Macro-instructions used to manage fragments -@@ -116,8 +120,8 @@ - #define EXT3_MAX_FRAG_SIZE 4096 - #define EXT3_MIN_FRAG_LOG_SIZE 10 - #ifdef __KERNEL__ --# define EXT3_FRAG_SIZE(s) ((s)->u.ext3_sb.s_frag_size) --# define EXT3_FRAGS_PER_BLOCK(s) ((s)->u.ext3_sb.s_frags_per_block) -+# define EXT3_FRAG_SIZE(s) (EXT3_SB(s)->s_frag_size) -+# define EXT3_FRAGS_PER_BLOCK(s) (EXT3_SB(s)->s_frags_per_block) - #else - # define EXT3_FRAG_SIZE(s) (EXT3_MIN_FRAG_SIZE << (s)->s_log_frag_size) - # define EXT3_FRAGS_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / EXT3_FRAG_SIZE(s)) -@@ -163,15 +167,13 @@ - /* - * Macro-instructions used to manage group descriptors - */ -+# define EXT3_BLOCKS_PER_GROUP(s) (EXT3_SB(s)->s_blocks_per_group) -+# define EXT3_INODES_PER_GROUP(s) (EXT3_SB(s)->s_inodes_per_group) - #ifdef __KERNEL__ --# define EXT3_BLOCKS_PER_GROUP(s) ((s)->u.ext3_sb.s_blocks_per_group) --# define EXT3_DESC_PER_BLOCK(s) ((s)->u.ext3_sb.s_desc_per_block) --# define EXT3_INODES_PER_GROUP(s) ((s)->u.ext3_sb.s_inodes_per_group) --# define EXT3_DESC_PER_BLOCK_BITS(s) ((s)->u.ext3_sb.s_desc_per_block_bits) -+# define EXT3_DESC_PER_BLOCK(s) (EXT3_SB(s)->s_desc_per_block) -+# define EXT3_DESC_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_desc_per_block_bits) - #else --# define EXT3_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) - # define EXT3_DESC_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_group_desc)) --# define EXT3_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) - #endif - - /* -@@ -344,7 +347,7 @@ - #ifndef _LINUX_EXT2_FS_H - #define clear_opt(o, opt) o &= ~EXT3_MOUNT_##opt - #define set_opt(o, opt) o |= EXT3_MOUNT_##opt --#define test_opt(sb, opt) ((sb)->u.ext3_sb.s_mount_opt & \ -+#define test_opt(sb, opt) (EXT3_SB(sb)->s_mount_opt & \ - EXT3_MOUNT_##opt) - #else - #define EXT2_MOUNT_NOLOAD EXT3_MOUNT_NOLOAD -@@ -441,17 +443,11 @@ - /*EC*/ __u32 s_reserved[197]; /* Padding to the end of the block */ - }; - --#ifdef __KERNEL__ --#define EXT3_SB(sb) (&((sb)->u.ext3_sb)) --#define EXT3_I(inode) (&((inode)->u.ext3_i)) --#else --/* Assume that user mode programs are passing in an ext3fs superblock, not -- * a kernel struct super_block. This will allow us to call the feature-test -- * macros from user land. */ --#define EXT3_SB(sb) (sb) --#endif -- --#define NEXT_ORPHAN(inode) (inode)->u.ext3_i.i_dtime -+#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime -+static inline struct inode *orphan_list_entry(struct list_head *l) -+{ -+ return list_entry(l, struct inode, u.ext3_i.i_orphan); -+} - - /* - * Codes for operating systems ---- ./include/linux/ext3_jbd.h.orig Tue May 7 14:44:08 2002 -+++ ./include/linux/ext3_jbd.h Tue May 7 14:44:43 2002 -@@ -291,7 +291,7 @@ - return 1; - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) - return 1; -- if (inode->u.ext3_i.i_flags & EXT3_JOURNAL_DATA_FL) -+ if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) - return 1; - return 0; - } diff --git a/lustre/extN/ext3-largefile.diff b/lustre/extN/ext3-largefile.diff deleted file mode 100644 index db41aab..0000000 --- a/lustre/extN/ext3-largefile.diff +++ /dev/null @@ -1,23 +0,0 @@ -Under rare conditions (filesystem corruption, really) it is possible -for ext3_dirty_inode() to require _two_ blocks for the transaction: one -for the inode and one to update the superblock - to set -EXT3_FEATURE_RO_COMPAT_LARGE_FILE. This causes the filesystem to go -BUG. - -So reserve an additional block for that eventuality. - - - fs/ext3/inode.c | 2 +- - 1 files changed, 1 insertion(+), 1 deletion(-) - ---- 25/fs/ext3/inode.c~ext3-transaction-reserved-blocks Sat Dec 14 18:28:21 2002 -+++ 25-akpm/fs/ext3/inode.c Sat Dec 14 18:28:21 2002 -@@ -2698,7 +2698,7 @@ void ext3_dirty_inode(struct inode *inod - handle_t *handle; - - lock_kernel(); -- handle = ext3_journal_start(inode, 1); -+ handle = ext3_journal_start(inode, 2); - if (IS_ERR(handle)) - goto out; - if (current_handle && diff --git a/lustre/extN/ext3-unmount_sync.diff b/lustre/extN/ext3-unmount_sync.diff deleted file mode 100644 index 1f9b796..0000000 --- a/lustre/extN/ext3-unmount_sync.diff +++ /dev/null @@ -1,59 +0,0 @@ -From adilger@clusterfs.com Mon Dec 2 10:26:44 2002 -Date: Mon, 2 Dec 2002 10:26:44 -0700 -From: Andreas Dilger -To: Lustre LLNL Mailing list , - Lustre Development Mailing List -Subject: Re: data corrupting bug in 2.4.20 ext3, data=journal -Message-ID: <20021202102644.H1422@schatzie.adilger.int> -Mail-Followup-To: Lustre LLNL Mailing list , - Lustre Development Mailing List -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2.5.1i -X-GPG-Key: 1024D/0D35BED6 -X-GPG-Fingerprint: 7A37 5D79 BF1B CECA D44F 8A29 A488 39F5 0D35 BED6 -Status: RO -Content-Length: 1160 -Lines: 39 - -Here is the new-improved fix for the ext3 discarding data at umount bug -discovered late last week. To be used instead of the previous ext3 fix. - -Sadly, this is completely unrelated to the problems Mike is having with -ext3 under UML, since it is an unmount-time problem. - ------ Forwarded message from "Stephen C. Tweedie" ----- -The attached patch seems to fix things for me. - -Cheers, - Stephen - - ---- linux-2.4-ext3merge/fs/ext3/super.c.=K0027=.orig 2002-12-02 15:35:13.000000000 +0000 -+++ linux-2.4-ext3merge/fs/ext3/super.c 2002-12-02 15:35:14.000000000 +0000 -@@ -1640,7 +1640,12 @@ - sb->s_dirt = 0; - target = log_start_commit(EXT3_SB(sb)->s_journal, NULL); - -- if (do_sync_supers) { -+ /* -+ * Tricky --- if we are unmounting, the write really does need -+ * to be synchronous. We can detect that by looking for NULL in -+ * sb->s_root. -+ */ -+ if (do_sync_supers || !sb->s_root) { - unlock_super(sb); - log_wait_commit(EXT3_SB(sb)->s_journal, target); - lock_super(sb); - - ------ End forwarded message ----- - -Cheers, Andreas --- -Andreas Dilger -http://sourceforge.net/projects/ext2resize/ -http://www-mddsp.enel.ucalgary.ca/People/adilger/ - - diff --git a/lustre/extN/ext3-use-after-free.diff b/lustre/extN/ext3-use-after-free.diff deleted file mode 100644 index 8cd673f..0000000 --- a/lustre/extN/ext3-use-after-free.diff +++ /dev/null @@ -1,65 +0,0 @@ - - -If ext3_add_nondir() fails it will do an iput() of the inode. But we -continue to run ext3_mark_inode_dirty() against the potentially-freed -inode. This oopses when slab poisoning is enabled. - -Fix it so that we only run ext3_mark_inode_dirty() if the inode was -successfully instantiated. - -This bug was added in 2.4.20-pre9. - - - fs/ext3/namei.c | 11 +++++------ - 1 files changed, 5 insertions(+), 6 deletions(-) - ---- 24/fs/ext3/namei.c~ext3-use-after-free Sun Dec 15 11:27:50 2002 -+++ 24-akpm/fs/ext3/namei.c Sun Dec 15 11:27:50 2002 -@@ -429,8 +429,11 @@ static int ext3_add_nondir(handle_t *han - { - int err = ext3_add_entry(handle, dentry, inode); - if (!err) { -- d_instantiate(dentry, inode); -- return 0; -+ err = ext3_mark_inode_dirty(handle, inode); -+ if (err == 0) { -+ d_instantiate(dentry, inode); -+ return 0; -+ } - } - ext3_dec_count(handle, inode); - iput(inode); -@@ -465,7 +468,6 @@ static int ext3_create (struct inode * d - inode->i_fop = &ext3_file_operations; - inode->i_mapping->a_ops = &ext3_aops; - err = ext3_add_nondir(handle, dentry, inode); -- ext3_mark_inode_dirty(handle, inode); - } - ext3_journal_stop(handle, dir); - return err; -@@ -490,7 +492,6 @@ static int ext3_mknod (struct inode * di - if (!IS_ERR(inode)) { - init_special_inode(inode, mode, rdev); - err = ext3_add_nondir(handle, dentry, inode); -- ext3_mark_inode_dirty(handle, inode); - } - ext3_journal_stop(handle, dir); - return err; -@@ -934,7 +935,6 @@ static int ext3_symlink (struct inode * - } - inode->u.ext3_i.i_disksize = inode->i_size; - err = ext3_add_nondir(handle, dentry, inode); -- ext3_mark_inode_dirty(handle, inode); - out_stop: - ext3_journal_stop(handle, dir); - return err; -@@ -971,7 +971,6 @@ static int ext3_link (struct dentry * ol - atomic_inc(&inode->i_count); - - err = ext3_add_nondir(handle, dentry, inode); -- ext3_mark_inode_dirty(handle, inode); - ext3_journal_stop(handle, dir); - return err; - } - -_ diff --git a/lustre/extN/extN-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-iget-debug.diff b/lustre/extN/extN-iget-debug.diff deleted file mode 100644 index 9714e35..0000000 --- a/lustre/extN/extN-iget-debug.diff +++ /dev/null @@ -1,48 +0,0 @@ ---- linux/fs/ext3/namei.c.orig Thu Jan 30 01:15:13 2003 -+++ linux/fs/ext3/namei.c Sat Feb 1 00:33:46 2003 -@@ -710,6 +710,24 @@ - return ret; - } - -+static int extN_find_inode(struct inode *inode, unsigned long ino, -+ void *opaque) -+{ -+ const char *name = NULL; -+ int len = 0; -+ -+ if (opaque) { -+ struct dentry *dentry = opaque; -+ name = dentry->d_name.name; -+ len = dentry->d_name.len; -+ } -+ printk(KERN_INFO "finding inode %s:%lu (%p) count %d (%p = %*s)\n", -+ kdevname(inode->i_dev), ino, inode, atomic_read(&inode->i_count), -+ opaque, len, name ? name : ""); -+ -+ return 1; -+} -+ - static struct dentry *extN_lookup(struct inode * dir, struct dentry *dentry) - { - struct inode * inode; -@@ -724,7 +742,7 @@ - if (bh) { - unsigned long ino = le32_to_cpu(de->inode); - brelse (bh); -- inode = iget(dir->i_sb, ino); -+ inode = iget4(dir->i_sb, ino, extN_find_inode, dentry); - - if (!inode) - return ERR_PTR(-EACCES); ---- linux/fs/ext3/inode.c.orig Thu Jan 30 01:15:13 2003 -+++ linux/fs/ext3/inode.c Sat Feb 1 00:34:45 2003 -@@ -166,6 +166,9 @@ - */ - void extN_put_inode (struct inode * inode) - { -+ printk(KERN_INFO "putting inode %s:%lu (%p) count %d\n", -+ kdevname(inode->i_dev), inode->i_ino, inode, -+ atomic_read(&inode->i_count)); - extN_discard_prealloc (inode); - } - diff --git a/lustre/extN/extN-misc-fixup.diff b/lustre/extN/extN-misc-fixup.diff deleted file mode 100644 index db0bc0f..0000000 --- a/lustre/extN/extN-misc-fixup.diff +++ /dev/null @@ -1,23 +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; -@@ -1560,6 +1560,7 @@ - unlock_kernel(); - return ret; - } -+EXPORT_SYMBOL(extN_force_commit); /* here to avoid potential patch collisions */ - - /* - * Ext3 always journals updates to the superblock itself, so we don't diff --git a/lustre/extN/extN-noread.diff b/lustre/extN/extN-noread.diff deleted file mode 100644 index 463516c..0000000 --- a/lustre/extN/extN-noread.diff +++ /dev/null @@ -1,225 +0,0 @@ -diff -ru lustre-head/fs/extN/ialloc.c lustre/fs/extN/ialloc.c ---- lustre-head/fs/extN/ialloc.c Mon Dec 23 10:02:58 2002 -+++ lustre/fs/extN/ialloc.c Mon Dec 23 09:46:20 2002 -@@ -289,6 +289,37 @@ - } - - /* -+ * @block_group: block group of inode -+ * @offset: relative offset of inode within @block_group -+ * -+ * Check whether any of the inodes in this disk block are in use. -+ * -+ * Caller must be holding superblock lock (group/bitmap read lock in future). -+ */ -+int extN_itable_block_used(struct super_block *sb, unsigned int block_group, -+ int offset) -+{ -+ int bitmap_nr = load_inode_bitmap(sb, block_group); -+ int inodes_per_block; -+ unsigned long inum, iend; -+ struct buffer_head *ibitmap; -+ -+ if (bitmap_nr < 0) -+ return 1; -+ -+ inodes_per_block = sb->s_blocksize / EXTN_SB(sb)->s_inode_size; -+ inum = offset & ~(inodes_per_block - 1); -+ iend = inum + inodes_per_block; -+ ibitmap = EXTN_SB(sb)->s_inode_bitmap[bitmap_nr]; -+ for (; inum < iend; inum++) { -+ if (inum != offset && extN_test_bit(inum, ibitmap->b_data)) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/* - * There are two policies for allocating an inode. If the new inode is - * a directory, then a forward search is made for a block group with both - * free space and a low directory-to-inode ratio; if that fails, then of -@@ -312,6 +343,7 @@ - struct extN_group_desc * gdp; - struct extN_group_desc * tmp; - struct extN_super_block * es; -+ struct extN_iloc iloc; - int err = 0; - - /* Cannot create files in a deleted directory */ -@@ -505,7 +538,7 @@ - ei->i_prealloc_count = 0; - #endif - ei->i_block_group = i; -- -+ - if (ei->i_flags & EXTN_SYNC_FL) - inode->i_flags |= S_SYNC; - if (IS_SYNC(inode)) -@@ -514,9 +547,18 @@ - inode->i_generation = sbi->s_next_generation++; - - ei->i_state = EXTN_STATE_NEW; -- err = extN_mark_inode_dirty(handle, inode); -+ err = extN_get_inode_loc_new(inode, &iloc, 1); - if (err) goto fail; -- -+ BUFFER_TRACE(iloc->bh, "get_write_access"); -+ err = extN_journal_get_write_access(handle, iloc.bh); -+ if (err) { -+ brelse(iloc.bh); -+ iloc.bh = NULL; -+ goto fail; -+ } -+ err = extN_mark_iloc_dirty(handle, inode, &iloc); -+ if (err) goto fail; -+ - unlock_super (sb); - if(DQUOT_ALLOC_INODE(inode)) { - DQUOT_DROP(inode); -diff -ru lustre-head/fs/extN/inode.c lustre/fs/extN/inode.c ---- lustre-head/fs/extN/inode.c Mon Dec 23 10:02:58 2002 -+++ lustre/fs/extN/inode.c Mon Dec 23 09:50:25 2002 -@@ -2011,23 +1994,32 @@ - extN_journal_stop(handle, inode); - } - --/* -- * extN_get_inode_loc returns with an extra refcount against the -- * inode's underlying buffer_head on success. -- */ -+extern int extN_itable_block_used(struct super_block *sb, -+ unsigned int block_group, -+ int offset); -+ -+#define NUM_INODE_PREREAD 16 - --int extN_get_inode_loc (struct inode *inode, struct extN_iloc *iloc) -+/* -+ * extN_get_inode_loc returns with an extra refcount against the inode's -+ * underlying buffer_head on success. If this is for a new inode allocation -+ * (new is non-zero) then we may be able to optimize away the read if there -+ * are no other in-use inodes in this inode table block. If we need to do -+ * a read, then read in a whole chunk of blocks to avoid blocking again soon -+ * if we are doing lots of creates/updates. -+ */ -+int extN_get_inode_loc_new(struct inode *inode, struct extN_iloc *iloc, int new) - { - struct super_block *sb = inode->i_sb; - struct extN_sb_info *sbi = EXTN_SB(sb); -- struct buffer_head *bh = 0; -+ struct buffer_head *bh[NUM_INODE_PREREAD]; - unsigned long block; - unsigned long block_group; - unsigned long group_desc; - unsigned long desc; - unsigned long offset; - struct extN_group_desc * gdp; -- -+ - if ((inode->i_ino != EXTN_ROOT_INO && - inode->i_ino != EXTN_JOURNAL_INO && - inode->i_ino < EXTN_FIRST_INO(sb)) || -@@ -2042,38 +2034,86 @@ - } - group_desc = block_group >> sbi->s_desc_per_block_bits; - desc = block_group & (sbi->s_desc_per_block - 1); -- bh = sbi->s_group_desc[group_desc]; -- if (!bh) { -+ if (!sbi->s_group_desc[group_desc]) { - extN_error(sb, __FUNCTION__, "Descriptor not loaded"); - goto bad_inode; - } - -- gdp = (struct extN_group_desc *) bh->b_data; -+ gdp = (struct extN_group_desc *)(sbi->s_group_desc[group_desc]->b_data); -+ - /* - * Figure out the offset within the block group inode table - */ -- offset = ((inode->i_ino - 1) % sbi->s_inodes_per_group) * -- sbi->s_inode_size; -+ offset = ((inode->i_ino - 1) % sbi->s_inodes_per_group); -+ - block = le32_to_cpu(gdp[desc].bg_inode_table) + -- (offset >> EXTN_BLOCK_SIZE_BITS(sb)); -- if (!(bh = sb_bread(sb, block))) { -- extN_error (sb, __FUNCTION__, -- "unable to read inode block - " -- "inode=%lu, block=%lu", inode->i_ino, block); -- goto bad_inode; -+ (offset * sbi->s_inode_size >> EXTN_BLOCK_SIZE_BITS(sb)); -+ -+ bh[0] = sb_getblk(sb, block); -+ if (buffer_uptodate(bh[0])) -+ goto done; -+ -+ /* If we don't really need to read this block, and it isn't already -+ * in memory, then we just zero it out. Otherwise, we keep the -+ * current block contents (deleted inode data) for posterity. -+ */ -+ if (new && !extN_itable_block_used(sb, block_group, offset)) { -+ lock_buffer(bh[0]); -+ memset(bh[0]->b_data, 0, bh[0]->b_size); -+ mark_buffer_uptodate(bh[0], 1); -+ unlock_buffer(bh[0]); -+ } else { -+ unsigned long block_end, itable_end; -+ int count = 1; -+ -+ itable_end = le32_to_cpu(gdp[desc].bg_inode_table) + -+ sbi->s_itb_per_group; -+ block_end = block + NUM_INODE_PREREAD; -+ if (block_end > itable_end) -+ block_end = itable_end; -+ -+ for (; block < block_end; block++) { -+ bh[count] = sb_getblk(sb, block); -+ if (count && (buffer_uptodate(bh[count]) || -+ buffer_locked(bh[count]))) { -+ __brelse(bh[count]); -+ } else -+ count++; -+ } -+ -+ ll_rw_block(READ, count, bh); -+ -+ /* Release all but the block we actually need (bh[0]) */ -+ while (--count > 0) -+ __brelse(bh[count]); -+ -+ wait_on_buffer(bh[0]); -+ if (!buffer_uptodate(bh[0])) { -+ extN_error(sb, __FUNCTION__, -+ "unable to read inode block - " -+ "inode=%lu, block=%lu", inode->i_ino, -+ bh[0]->b_blocknr); -+ goto bad_inode; -+ } - } -- offset &= (EXTN_BLOCK_SIZE(sb) - 1); -+ done: -+ offset = (offset * sbi->s_inode_size) & (EXTN_BLOCK_SIZE(sb) - 1); - -- iloc->bh = bh; -- iloc->raw_inode = (struct extN_inode *) (bh->b_data + offset); -+ iloc->bh = bh[0]; -+ iloc->raw_inode = (struct extN_inode *)(bh[0]->b_data + offset); - iloc->block_group = block_group; -- -+ - return 0; -- -+ - bad_inode: - return -EIO; - } - -+int extN_get_inode_loc(struct inode *inode, struct extN_iloc *iloc) -+{ -+ return extN_get_inode_loc_new(inode, iloc, 0); -+} -+ - void extN_read_inode(struct inode * inode) - { - struct extN_iloc iloc; diff --git a/lustre/extN/extN-san.diff b/lustre/extN/extN-san.diff deleted file mode 100644 index 4d0f277..0000000 --- a/lustre/extN/extN-san.diff +++ /dev/null @@ -1,88 +0,0 @@ ---- lustre/extN/inode.orig.c 2002-12-29 18:48:56.000000000 +0800 -+++ lustre/extN/inode.c 2002-12-29 19:17:24.000000000 +0800 -@@ -2728,3 +2728,85 @@ - * here, in extN_aops_journal_start() to ensure that the forthcoming "see if we - * need to extend" test in extN_prepare_write() succeeds. - */ -+ -+/* for each block: 1 ind + 1 dind + 1 tind -+ * for each block: 3 bitmap blocks -+ * for each block: 3 group descriptor blocks -+ * i inode block -+ * 1 superblock -+ * 2 * EXTN_SINGLEDATA_TRANS_BLOCKS for the quote files -+ * ((1+1+1) * 3 * nblocks) + 1 + 1 + 2 * EXTN_SINGLEDATA_TRANS_BLOCKS -+ * -+ * XXX assuming: -+ * (1) fs logic block size == page size -+ * (2) extN in writeback mode -+ */ -+static inline int extN_san_write_trans_blocks(int nblocks) -+{ -+ int ret; -+ -+ ret = (1 + 1 + 1) * 3 * nblocks + 1 + 1; -+ -+#ifdef CONFIG_QUOTA -+ ret += 2 * EXTN_SINGLEDATA_TRANS_BLOCKS; -+#endif -+ -+ return ret; -+} -+ -+/* Alloc blocks for an inode, while don't create any buffer/page -+ * for data I/O; set the inode size if file is extended. -+ * -+ * @inode: target inode -+ * @blocks: array of logic block number -+ * @nblocks: how many blocks need be alloced -+ * @newsize: new filesize we should set -+ * -+ * return: 0 success, otherwise failed -+ * (*blocks) contains physical block number alloced -+ * -+ * XXX this assume the fs block size == page size -+ */ -+int extN_prep_san_write(struct inode *inode, long *blocks, -+ int nblocks, loff_t newsize) -+{ -+ handle_t *handle; -+ struct buffer_head bh_tmp; -+ int needed_blocks; -+ int i, ret = 0, ret2; -+ -+ needed_blocks = extN_san_write_trans_blocks(nblocks); -+ -+ lock_kernel(); -+ handle = extN_journal_start(inode, needed_blocks); -+ if (IS_ERR(handle)) { -+ unlock_kernel(); -+ return PTR_ERR(handle); -+ } -+ unlock_kernel(); -+ -+ /* alloc blocks one by one */ -+ for (i = 0; i < nblocks; i++) { -+ ret = extN_get_block_handle(handle, inode, blocks[i], -+ &bh_tmp, 1); -+ if (ret) -+ break; -+ -+ blocks[i] = bh_tmp.b_blocknr; -+ } -+ -+ /* set inode size if needed */ -+ if (!ret && (newsize > inode->i_size)) { -+ inode->i_size = newsize; -+ extN_mark_inode_dirty(handle, inode); -+ } -+ -+ lock_kernel(); -+ ret2 = extN_journal_stop(handle, inode); -+ unlock_kernel(); -+ -+ if (!ret) -+ ret = ret2; -+ return ret; -+} -+EXPORT_SYMBOL(extN_prep_san_write); diff --git a/lustre/extN/extN-wantedi.diff b/lustre/extN/extN-wantedi.diff deleted file mode 100644 index a55aec0..0000000 --- a/lustre/extN/extN-wantedi.diff +++ /dev/null @@ -1,163 +0,0 @@ ---- lustre/extN-clean/namei.c 2002-12-30 05:56:09.000000000 -0500 -+++ lustre/extN/namei.c 2002-12-30 06:29:39.000000000 -0500 -@@ -1224,7 +1224,8 @@ - if (IS_SYNC(dir)) - handle->h_sync = 1; - -- inode = extN_new_inode (handle, dir, mode); -+ inode = extN_new_inode (handle, dir, mode, -+ (unsigned long)dentry->d_fsdata); - err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - inode->i_op = &extN_file_inode_operations; -@@ -1254,7 +1254,8 @@ - if (IS_SYNC(dir)) - handle->h_sync = 1; - -- inode = extN_new_inode (handle, dir, mode); -+ inode = extN_new_inode (handle, dir, mode, -+ (unsigned long)dentry->d_fsdata); - err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - init_special_inode(inode, mode, rdev); -@@ -1286,7 +1286,8 @@ - if (IS_SYNC(dir)) - handle->h_sync = 1; - -- inode = extN_new_inode (handle, dir, S_IFDIR | mode); -+ inode = extN_new_inode (handle, dir, S_IFDIR | mode, -+ (unsigned long)dentry->d_fsdata); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; -@@ -1680,7 +1681,8 @@ - if (IS_SYNC(dir)) - handle->h_sync = 1; - -- inode = extN_new_inode (handle, dir, S_IFLNK|S_IRWXUGO); -+ inode = extN_new_inode (handle, dir, S_IFLNK|S_IRWXUGO, -+ (unsigned long)dentry->d_fsdata); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; ---- lustre/extN-clean/ialloc.c 2002-12-28 23:56:42.000000000 -0500 -+++ lustre/extN/ialloc.c 2002-12-30 06:29:39.000000000 -0500 -@@ -329,8 +329,8 @@ - * For other inodes, search forward from the parent directory's block - * group to find a free inode. - */ --struct inode * extN_new_inode (handle_t *handle, -- const struct inode * dir, int mode) -+struct inode *extN_new_inode(handle_t *handle, const struct inode *dir, -+ int mode, unsigned long goal) - { - struct super_block * sb; - struct buffer_head * bh; -@@ -360,6 +361,38 @@ - - lock_super (sb); - es = sbi->s_es; -+ -+ if (goal) { -+ i = (goal - 1) / EXTN_INODES_PER_GROUP(sb); -+ j = (goal - 1) % EXTN_INODES_PER_GROUP(sb); -+ gdp = extN_get_group_desc(sb, i, &bh2); -+ -+ bitmap_nr = load_inode_bitmap (sb, i); -+ if (bitmap_nr < 0) -+ goto fail; -+ -+ bh = sbi->s_inode_bitmap[bitmap_nr]; -+ -+ BUFFER_TRACE(bh, "get_write_access"); -+ err = extN_journal_get_write_access(handle, bh); -+ if (err) goto fail; -+ -+ if (extN_set_bit(j, bh->b_data)) { -+ printk(KERN_ERR "goal inode %lu unavailable\n", goal); -+ /* Oh well, we tried. */ -+ goto repeat; -+ } -+ -+ BUFFER_TRACE(bh, "call extN_journal_dirty_metadata"); -+ err = extN_journal_dirty_metadata(handle, bh); -+ if (err) goto fail; -+ -+ /* We've shortcircuited the allocation system successfully, -+ * now finish filling in the inode. -+ */ -+ goto have_bit_and_group; -+ } -+ - repeat: - gdp = NULL; - i = 0; -@@ -474,6 +509,7 @@ - } - goto repeat; - } -+have_bit_and_group: - j += i * sbi->s_inodes_per_group + 1; - if (j < sbi->s_first_ino || j > le32_to_cpu(es->s_inodes_count)) { - extN_error (sb, "extN_new_inode", ---- lustre/extN-clean/ioctl.c 2002-12-28 23:56:42.000000000 -0500 -+++ lustre/extN/ioctl.c 2002-12-30 06:29:39.000000000 -0500 -@@ -24,6 +24,31 @@ - extN_debug ("cmd = %u, arg = %lu\n", cmd, arg); - - switch (cmd) { -+ case EXTN_IOC_CREATE_INUM: { -+ char name[32]; -+ struct dentry *dchild, *dparent; -+ int rc = 0; -+ -+ dparent = list_entry(inode->i_dentry.next, struct dentry, -+ d_alias); -+ snprintf(name, sizeof name, "%lu", arg); -+ dchild = lookup_one_len(name, dparent, strlen(name)); -+ if (dchild->d_inode) { -+ printk(KERN_ERR "%*s/%lu already exists (ino %lu)\n", -+ dparent->d_name.len, dparent->d_name.name, arg, -+ dchild->d_inode->i_ino); -+ rc = -EEXIST; -+ } else { -+ dchild->d_fsdata = (void *)arg; -+ rc = vfs_create(inode, dchild, 0644); -+ if (rc) -+ printk(KERN_ERR "vfs_create: %d\n", rc); -+ else if (dchild->d_inode->i_ino != arg) -+ rc = -EEXIST; -+ } -+ dput(dchild); -+ return rc; -+ } - case EXTN_IOC_GETFLAGS: - flags = ei->i_flags & EXTN_FL_USER_VISIBLE; - return put_user(flags, (int *) arg); ---- lustre/include/linux/extN_fs.h~ 2002-12-30 06:01:43.000000000 -0500 -+++ lustre/include/linux/extN_fs.h 2002-12-30 06:02:51.000000000 -0500 -@@ -200,6 +200,7 @@ - #define EXTN_IOC_SETFLAGS _IOW('f', 2, long) - #define EXTN_IOC_GETVERSION _IOR('f', 3, long) - #define EXTN_IOC_SETVERSION _IOW('f', 4, long) -+/* EXTN_IOC_CREATE_INUM at bottom of file (visible to kernel and user). */ - #define EXTN_IOC_GETVERSION_OLD _IOR('v', 1, long) - #define EXTN_IOC_SETVERSION_OLD _IOW('v', 2, long) - #ifdef CONFIG_JBD_DEBUG -@@ -632,7 +633,8 @@ - extern int extN_sync_file (struct file *, struct dentry *, int); - - /* ialloc.c */ --extern struct inode * extN_new_inode (handle_t *, const struct inode *, int); -+extern struct inode * extN_new_inode (handle_t *, const struct inode *, int, -+ unsigned long); - extern void extN_free_inode (handle_t *, struct inode *); - extern struct inode * extN_orphan_get (struct super_block *, ino_t); - extern unsigned long extN_count_free_inodes (struct super_block *); -@@ -714,4 +716,6 @@ - - #endif /* __KERNEL__ */ - -+#define EXTN_IOC_CREATE_INUM _IOW('f', 5, long) -+ - #endif /* _LINUX_EXTN_FS_H */ 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 4251251..0000000 --- a/lustre/extN/htree-ext3-2.4.18.diff +++ /dev/null @@ -1,1201 +0,0 @@ ---- ./fs/ext3/super.c 2002/03/05 06:18:59 2.1 -+++ ./fs/ext3/super.c 2002/03/05 06:26:56 -@@ -529,6 +529,12 @@ - "EXT3 Check option not supported\n"); - #endif - } -+ else if (!strcmp (this_char, "index")) -+#ifdef CONFIG_EXT3_INDEX -+ set_opt (*mount_options, INDEX); -+#else -+ printk("EXT3 index option not supported\n"); -+#endif - else if (!strcmp (this_char, "debug")) - set_opt (*mount_options, DEBUG); - else if (!strcmp (this_char, "errors")) { -@@ -702,6 +708,12 @@ 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,437 @@ - #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) - #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b)) - -+static struct buffer_head *ext3_append(handle_t *handle, -+ struct inode *inode, -+ u32 *block, int *err) -+{ -+ struct buffer_head *bh; -+ -+ *block = inode->i_size >> inode->i_sb->s_blocksize_bits; -+ -+ if ((bh = ext3_bread(handle, inode, *block, 1, err))) { -+ inode->i_size += inode->i_sb->s_blocksize; -+ EXT3_I(inode)->i_disksize = inode->i_size; -+ ext3_journal_get_write_access(handle,bh); -+ } -+ return bh; -+} -+ -+#ifndef assert -+#define assert(test) J_ASSERT(test) -+#endif -+ -+#ifndef swap -+#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0) -+#endif -+ -+typedef struct { u32 v; } le_u32; -+typedef struct { u16 v; } le_u16; -+ -+#define dxtrace_on(command) command -+#define dxtrace_off(command) -+ -+struct fake_dirent -+{ -+ /*le*/u32 inode; -+ /*le*/u16 rec_len; -+ u8 name_len; -+ u8 file_type; -+}; -+ -+struct dx_countlimit -+{ -+ le_u16 limit; -+ le_u16 count; -+}; -+ -+struct dx_entry -+{ -+ le_u32 hash; -+ le_u32 block; -+}; -+ -+/* -+ * dx_root_info is laid out so that if it should somehow get overlaid by a -+ * dirent the two low bits of the hash version will be zero. Therefore, the -+ * hash version mod 4 should never be 0. Sincerely, the paranoia department. -+ */ -+ -+struct dx_root -+{ -+ struct fake_dirent dot; -+ char dot_name[4]; -+ struct fake_dirent dotdot; -+ char dotdot_name[4]; -+ struct dx_root_info -+ { -+ le_u32 reserved_zero; -+ u8 hash_version; /* 0 now, 1 at release */ -+ u8 info_length; /* 8 */ -+ u8 indirect_levels; -+ u8 unused_flags; -+ } -+ info; -+ struct dx_entry entries[0]; -+}; -+ -+struct dx_node -+{ -+ struct fake_dirent fake; -+ struct dx_entry entries[0]; -+}; -+ -+ -+struct dx_frame -+{ -+ struct buffer_head *bh; -+ struct dx_entry *entries; -+ struct dx_entry *at; -+}; -+ -+struct dx_map_entry -+{ -+ u32 hash; -+ u32 offs; -+}; -+ -+typedef struct ext3_dir_entry_2 ext3_dirent; -+static inline unsigned dx_get_block (struct dx_entry *entry); -+static void dx_set_block (struct dx_entry *entry, unsigned value); -+static inline unsigned dx_get_hash (struct dx_entry *entry); -+static void dx_set_hash (struct dx_entry *entry, unsigned value); -+static unsigned dx_get_count (struct dx_entry *entries); -+static unsigned dx_get_limit (struct dx_entry *entries); -+static void dx_set_count (struct dx_entry *entries, unsigned value); -+static void dx_set_limit (struct dx_entry *entries, unsigned value); -+static unsigned dx_root_limit (struct inode *dir, unsigned infosize); -+static unsigned dx_node_limit (struct inode *dir); -+static unsigned dx_hack_hash (const u8 *name, int len); -+static struct dx_frame *dx_probe (struct inode *dir, u32 hash, struct dx_frame *frame); -+static void dx_release (struct dx_frame *frames); -+static int dx_make_map (ext3_dirent *de, int size, struct dx_map_entry map[]); -+static void dx_sort_map(struct dx_map_entry *map, unsigned count); -+static ext3_dirent *dx_copy_dirents (char *from, char *to, -+ struct dx_map_entry *map, int count); -+static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); -+ -+ -+#ifdef CONFIG_EXT3_INDEX -+/* -+ * Future: use high four bits of block for coalesce-on-delete flags -+ * Mask them off for now. -+ */ -+ -+static inline unsigned dx_get_block (struct dx_entry *entry) -+{ -+ return le32_to_cpu(entry->block.v) & 0x00ffffff; -+} -+ -+static inline void dx_set_block (struct dx_entry *entry, unsigned value) -+{ -+ entry->block.v = cpu_to_le32(value); -+} -+ -+static inline unsigned dx_get_hash (struct dx_entry *entry) -+{ -+ return le32_to_cpu(entry->hash.v); -+} -+ -+static inline void dx_set_hash (struct dx_entry *entry, unsigned value) -+{ -+ entry->hash.v = cpu_to_le32(value); -+} -+ -+static inline unsigned dx_get_count (struct dx_entry *entries) -+{ -+ return le16_to_cpu(((struct dx_countlimit *) entries)->count.v); -+} -+ -+static inline unsigned dx_get_limit (struct dx_entry *entries) -+{ -+ return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v); -+} -+ -+static inline void dx_set_count (struct dx_entry *entries, unsigned value) -+{ -+ ((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value); -+} -+ -+static inline void dx_set_limit (struct dx_entry *entries, unsigned value) -+{ -+ ((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value); -+} -+ -+static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize) -+{ -+ unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) - -+ EXT3_DIR_REC_LEN(2) - infosize; -+ return 0? 20: entry_space / sizeof(struct dx_entry); -+} -+ -+static inline unsigned dx_node_limit (struct inode *dir) -+{ -+ unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0); -+ return 0? 22: entry_space / sizeof(struct dx_entry); -+} -+ -+/* Hash function - not bad, but still looking for an ideal default */ -+ -+static unsigned dx_hack_hash (const u8 *name, int len) -+{ -+ u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9; -+ while (len--) -+ { -+ u32 hash = hash1 + (hash0 ^ (*name++ * 7152373)); -+ if (hash & 0x80000000) hash -= 0x7fffffff; -+ hash1 = hash0; -+ hash0 = hash; -+ } -+ return hash0; -+} -+ -+#define dx_hash(s,n) (dx_hack_hash(s,n) << 1) -+ -+/* -+ * Debug -+ */ -+#ifdef DX_DEBUG -+#define dxtrace dxtrace_on -+static void dx_show_index (char * label, struct dx_entry *entries) -+{ -+ int i, n = dx_get_count (entries); -+ printk("%s index ", label); -+ for (i = 0; i < n; i++) -+ { -+ printk("%x->%u ", i? dx_get_hash(entries + i): 0, dx_get_block(entries + i)); -+ } -+ printk("\n"); -+} -+ -+struct stats -+{ -+ unsigned names; -+ unsigned space; -+ unsigned bcount; -+}; -+ -+static struct stats dx_show_leaf (ext3_dirent *de, int size, int show_names) -+{ -+ unsigned names = 0, space = 0; -+ char *base = (char *) de; -+ printk("names: "); -+ while ((char *) de < base + size) -+ { -+ if (de->inode) -+ { -+ if (show_names) -+ { -+ int len = de->name_len; -+ char *name = de->name; -+ while (len--) printk("%c", *name++); -+ printk(":%x.%u ", dx_hash (de->name, de->name_len), ((char *) de - base)); -+ } -+ space += EXT3_DIR_REC_LEN(de->name_len); -+ names++; -+ } -+ de = (ext3_dirent *) ((char *) de + le16_to_cpu(de->rec_len)); -+ } -+ printk("(%i)\n", names); -+ return (struct stats) { names, space, 1 }; -+} -+ -+struct stats dx_show_entries (struct inode *dir, struct dx_entry *entries, int levels) -+{ -+ unsigned blocksize = dir->i_sb->s_blocksize; -+ unsigned count = dx_get_count (entries), names = 0, space = 0, i; -+ unsigned bcount = 0; -+ struct buffer_head *bh; -+ int err; -+ printk("%i indexed blocks...\n", count); -+ for (i = 0; i < count; i++, entries++) -+ { -+ u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0; -+ u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash; -+ struct stats stats; -+ printk("%s%3u:%03u hash %8x/%8x ",levels?"":" ", i, block, hash, range); -+ if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue; -+ stats = levels? -+ dx_show_entries (dir, ((struct dx_node *) bh->b_data)->entries, levels - 1): -+ dx_show_leaf ((ext3_dirent *) bh->b_data, blocksize, 0); -+ names += stats.names; -+ space += stats.space; -+ bcount += stats.bcount; -+ brelse (bh); -+ } -+ if (bcount) -+ printk("%snames %u, fullness %u (%u%%)\n", levels?"":" ", -+ names, space/bcount,(space/bcount)*100/blocksize); -+ return (struct stats) { names, space, bcount}; -+} -+#else -+#define dxtrace dxtrace_off -+#endif -+ -+/* -+ * Probe for a directory leaf block to search -+ */ -+ -+static struct dx_frame * -+dx_probe(struct inode *dir, u32 hash, struct dx_frame *frame_in) -+{ -+ unsigned count, indirect; -+ struct dx_entry *at, *entries, *p, *q, *m; -+ struct dx_root *root; -+ struct buffer_head *bh; -+ struct dx_frame *frame = frame_in; -+ int err; -+ -+ frame->bh = NULL; -+ if (!(bh = ext3_bread(NULL, dir, 0, 0, &err))) -+ goto fail; -+ root = (struct dx_root *) bh->b_data; -+ if (root->info.hash_version > 0 || root->info.unused_flags & 1) { -+ brelse(bh); -+ goto fail; -+ } -+ if ((indirect = root->info.indirect_levels) > 1) { -+ brelse(bh); -+ goto fail; -+ } -+ entries = (struct dx_entry *) (((char *) &root->info) + root->info.info_length); -+ assert (dx_get_limit(entries) == dx_root_limit(dir, root->info.info_length)); -+ dxtrace (printk("Look up %x", hash)); -+ while (1) -+ { -+ count = dx_get_count(entries); -+ assert (count && count <= dx_get_limit(entries)); -+ p = entries + 1; -+ q = entries + count - 1; -+ while (p <= q) -+ { -+ m = p + (q - p)/2; -+ dxtrace(printk(".")); -+ if (dx_get_hash(m) > hash) -+ q = m - 1; -+ else -+ p = m + 1; -+ } -+ -+ if (0) // linear search cross check -+ { -+ unsigned n = count - 1; -+ at = entries; -+ while (n--) -+ { -+ dxtrace(printk(",")); -+ if (dx_get_hash(++at) > hash) -+ { -+ at--; -+ break; -+ } -+ } -+ assert (at == p - 1); -+ } -+ -+ at = p - 1; -+ dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at))); -+ frame->bh = bh; -+ frame->entries = entries; -+ frame->at = at; -+ if (!indirect--) return frame; -+ if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0,&err))) -+ goto fail2; -+ at = entries = ((struct dx_node *) bh->b_data)->entries; -+ assert (dx_get_limit(entries) == dx_node_limit (dir)); -+ frame++; -+ } -+fail2: -+ while (frame >= frame_in) { -+ brelse(frame->bh); -+ frame--; -+ } -+fail: -+ return NULL; -+} -+ -+static void dx_release (struct dx_frame *frames) -+{ -+ if (frames[0].bh == NULL) -+ return; -+ -+ if (((struct dx_root *)frames[0].bh->b_data)->info.indirect_levels) -+ brelse (frames[1].bh); -+ brelse (frames[0].bh); -+} -+ -+/* -+ * Directory block splitting, compacting -+ */ -+ -+static int dx_make_map (ext3_dirent *de, int size, struct dx_map_entry map[]) -+{ -+ int count = 0; -+ char *base = (char *) de; -+ while ((char *) de < base + size) { -+ if (de->name_len && de->inode) { -+ map[count].hash = dx_hash (de->name, de->name_len); -+ map[count].offs = (u32) ((char *) de - base); -+ count++; -+ } -+ de = (ext3_dirent *) ((char *) de + le16_to_cpu(de->rec_len)); -+ } -+ return count; -+} -+ -+static void dx_sort_map (struct dx_map_entry *map, unsigned count) -+{ -+ struct dx_map_entry *p, *q, *top = map + count - 1; -+ int more; -+ /* Combsort until bubble sort doesn't suck */ -+ while (count > 2) -+ { -+ count = count*10/13; -+ if (count - 9 < 2) /* 9, 10 -> 11 */ -+ count = 11; -+ for (p = top, q = p - count; q >= map; p--, q--) -+ if (p->hash < q->hash) -+ swap(*p, *q); -+ } -+ /* Garden variety bubble sort */ -+ do { -+ more = 0; -+ q = top; -+ while (q-- > map) -+ { -+ if (q[1].hash >= q[0].hash) -+ continue; -+ swap(*(q+1), *q); -+ more = 1; -+ } -+ } while(more); -+} -+ -+static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block) -+{ -+ struct dx_entry *entries = frame->entries; -+ struct dx_entry *old = frame->at, *new = old + 1; -+ int count = dx_get_count(entries); -+ -+ assert(count < dx_get_limit(entries)); -+ assert(old < entries + count); -+ memmove(new + 1, new, (char *)(entries + count) - (char *)(new)); -+ dx_set_hash(new, hash); -+ dx_set_block(new, block); -+ dx_set_count(entries, count + 1); -+} -+#endif -+ -+static void ext3_update_dx_flag(struct inode *inode) -+{ -+ if (!test_opt(inode->i_sb, INDEX)) -+ EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL; -+} -+ - /* - * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure. - * -@@ -95,6 +529,15 @@ - } - - /* -+ * p is at least 6 bytes before the end of page -+ */ -+static inline ext3_dirent *ext3_next_entry(ext3_dirent *p) -+{ -+ return (ext3_dirent *)((char*)p + le16_to_cpu(p->rec_len)); -+} -+ -+ -+/* - * ext3_find_entry() - * - * finds an entry in the specified directory with the wanted name. It -@@ -105,6 +548,8 @@ - * The returned buffer_head has ->b_count elevated. The caller is expected - * to brelse() it when appropriate. - */ -+ -+ - static struct buffer_head * ext3_find_entry (struct dentry *dentry, - struct ext3_dir_entry_2 ** res_dir) - { -@@ -119,10 +564,70 @@ - int num = 0; - int nblocks, i, err; - struct inode *dir = dentry->d_parent->d_inode; -+ ext3_dirent *de, *top; - - *res_dir = NULL; - sb = dir->i_sb; -+ if (dentry->d_name.len > EXT3_NAME_LEN) -+ return NULL; -+ if (ext3_dx && is_dx(dir)) { -+ u32 hash = dx_hash(dentry->d_name.name, dentry->d_name.len); -+ struct dx_frame frames[2], *frame; -+ if (!(frame = dx_probe (dir, hash, frames))) -+ return NULL; -+dxnext: -+ block = dx_get_block(frame->at); -+ if (!(bh = ext3_bread (NULL,dir, block, 0, &err))) -+ goto dxfail; -+ de = (ext3_dirent *) bh->b_data; -+ top = (ext3_dirent *) ((char *) de + sb->s_blocksize - -+ EXT3_DIR_REC_LEN(0)); -+ for (; de < top; de = ext3_next_entry(de)) -+ if (ext3_match(dentry->d_name.len, dentry->d_name.name, de)) { -+ if (!ext3_check_dir_entry("ext3_find_entry", -+ dir, de, bh, -+ (block<b_data))) { -+ brelse (bh); -+ goto dxfail; -+ } -+ *res_dir = de; -+ goto dxfound; -+ } -+ brelse (bh); -+ /* Same hash continues in next block? Search on. */ -+ if (++(frame->at) == frame->entries + dx_get_count(frame->entries)) -+ { -+ struct buffer_head *bh2; -+ if (frame == frames) -+ goto dxfail; -+ if (++(frames->at) == frames->entries + dx_get_count(frames->entries)) -+ goto dxfail; -+ /* should omit read if not continued */ -+ if (!(bh2 = ext3_bread (NULL, dir, -+ dx_get_block(frames->at), -+ 0, &err))) -+ goto dxfail; -+ brelse (frame->bh); -+ frame->bh = bh2; -+ frame->at = frame->entries = ((struct dx_node *) bh2->b_data)->entries; -+ /* Subtle: the 0th entry has the count, find the hash in frame above */ -+ if ((dx_get_hash(frames->at) & -2) == hash) -+ goto dxnext; -+ goto dxfail; -+ } -+ if ((dx_get_hash(frame->at) & -2) == hash) -+ goto dxnext; -+dxfail: -+ dxtrace(printk("%s not found\n", name)); -+ dx_release (frames); -+ return NULL; -+dxfound: -+ dx_release (frames); -+ return bh; - -+ } -+ - nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb); - start = dir->u.ext3_i.i_dir_start_lookup; - if (start >= nblocks) -@@ -237,6 +748,90 @@ - de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; - } - -+static ext3_dirent * -+dx_copy_dirents (char *from, char *to, struct dx_map_entry *map, int count) -+{ -+ unsigned rec_len = 0; -+ -+ while (count--) { -+ ext3_dirent *de = (ext3_dirent *) (from + map->offs); -+ rec_len = EXT3_DIR_REC_LEN(de->name_len); -+ memcpy (to, de, rec_len); -+ ((ext3_dirent *) to)->rec_len = rec_len; -+ to += rec_len; -+ map++; -+ } -+ return (ext3_dirent *) (to - rec_len); -+} -+ -+#ifdef CONFIG_EXT3_INDEX -+static ext3_dirent *do_split(handle_t *handle, struct inode *dir, -+ struct buffer_head **bh,struct dx_frame *frame, -+ u32 hash, int *error) -+{ -+ unsigned count; -+ struct buffer_head *bh2; -+ u32 newblock; -+ u32 hash2; -+ struct dx_map_entry *map; -+ char *data1 = (*bh)->b_data, *data2, *data3; -+ unsigned split; -+ ext3_dirent *de, *de2; -+ -+ bh2 = ext3_append (handle, dir, &newblock, error); -+ if (!(bh2)) -+ { -+ brelse(*bh); -+ *bh = NULL; -+ return (ext3_dirent *)bh2; -+ } -+ -+ BUFFER_TRACE(*bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, *bh); -+ BUFFER_TRACE(frame->bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, frame->bh); -+ -+ data2 = bh2->b_data; -+ -+ map = kmalloc(sizeof(*map) * PAGE_CACHE_SIZE/EXT3_DIR_REC_LEN(1) + 1, -+ GFP_KERNEL); -+ if (!map) -+ panic("no memory for do_split\n"); -+ count = dx_make_map((ext3_dirent *)data1, dir->i_sb->s_blocksize, map); -+ split = count/2; // need to adjust to actual middle -+ dx_sort_map (map, count); -+ hash2 = map[split].hash; -+ dxtrace(printk("Split block %i at %x, %i/%i\n", -+ dx_get_block(frame->at), hash2, split, count-split)); -+ -+ /* Fancy dance to stay within two buffers */ -+ de2 = dx_copy_dirents (data1, data2, map + split, count - split); -+ data3 = (char *) de2 + de2->rec_len; -+ de = dx_copy_dirents (data1, data3, map, split); -+ memcpy(data1, data3, (char *) de + de->rec_len - data3); -+ de = (ext3_dirent *) ((char *) de - data3 + data1); // relocate de -+ de->rec_len = cpu_to_le16(data1 + dir->i_sb->s_blocksize - (char *)de); -+ de2->rec_len = cpu_to_le16(data2 + dir->i_sb->s_blocksize-(char *)de2); -+ dxtrace(dx_show_leaf((ext3_dirent *)data1, dir->i_sb->s_blocksize, 1)); -+ dxtrace(dx_show_leaf((ext3_dirent *)data2, dir->i_sb->s_blocksize, 1)); -+ -+ /* Which block gets the new entry? */ -+ if (hash >= hash2) -+ { -+ swap(*bh, bh2); -+ de = de2; -+ } -+ dx_insert_block(frame, hash2 + (hash2 == map[split-1].hash), newblock); -+ ext3_journal_dirty_metadata (handle, bh2); -+ brelse (bh2); -+ ext3_journal_dirty_metadata (handle, frame->bh); -+ dxtrace(dx_show_index ("frame", frame->entries)); -+ kfree(map); -+ return de; -+} -+#endif -+ -+ - /* - * ext3_add_entry() - * -@@ -255,118 +849,278 @@ - struct inode *inode) - { - struct inode *dir = dentry->d_parent->d_inode; -- const char *name = dentry->d_name.name; -- int namelen = dentry->d_name.len; - unsigned long offset; -- unsigned short rec_len; - struct buffer_head * bh; -- struct ext3_dir_entry_2 * de, * de1; -- struct super_block * sb; -+ ext3_dirent *de; -+ struct super_block * sb = dir->i_sb; - int retval; -+ unsigned short reclen = EXT3_DIR_REC_LEN(dentry->d_name.len); - -- sb = dir->i_sb; -+ unsigned nlen, rlen; -+ u32 block, blocks; -+ char *top; - -- if (!namelen) -+ if (!dentry->d_name.len) - return -EINVAL; -- bh = ext3_bread (handle, dir, 0, 0, &retval); -- if (!bh) -- return retval; -- rec_len = EXT3_DIR_REC_LEN(namelen); -- offset = 0; -- de = (struct ext3_dir_entry_2 *) bh->b_data; -- while (1) { -- if ((char *)de >= sb->s_blocksize + bh->b_data) { -- brelse (bh); -- bh = NULL; -- bh = ext3_bread (handle, dir, -- offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval); -- if (!bh) -- return retval; -- if (dir->i_size <= offset) { -- if (dir->i_size == 0) { -- brelse(bh); -- return -ENOENT; -+ if (ext3_dx && is_dx(dir)) { -+ struct dx_frame frames[2], *frame; -+ struct dx_entry *entries, *at; -+ u32 hash; -+ char *data1; -+ -+ hash = dx_hash(dentry->d_name.name, dentry->d_name.len); -+ /* FIXME: do something if dx_probe() fails here */ -+ frame = dx_probe(dir, hash, frames); -+ entries = frame->entries; -+ at = frame->at; -+ -+ if (!(bh = ext3_bread(handle,dir, dx_get_block(at), 0,&retval))) -+ goto dxfail1; -+ -+ BUFFER_TRACE(bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, bh); -+ -+ data1 = bh->b_data; -+ de = (ext3_dirent *) data1; -+ top = data1 + (0? 200: sb->s_blocksize); -+ while ((char *) de < top) -+ { -+ /* FIXME: check EEXIST and dir */ -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ if ((de->inode? rlen - nlen: rlen) >= reclen) -+ goto dx_add; -+ de = (ext3_dirent *) ((char *) de + rlen); -+ } -+ /* Block full, should compress but for now just split */ -+ dxtrace(printk("using %u of %u node entries\n", -+ dx_get_count(entries), dx_get_limit(entries))); -+ /* Need to split index? */ -+ if (dx_get_count(entries) == dx_get_limit(entries)) -+ { -+ u32 newblock; -+ unsigned icount = dx_get_count(entries); -+ int levels = frame - frames; -+ struct dx_entry *entries2; -+ struct dx_node *node2; -+ struct buffer_head *bh2; -+ if (levels && dx_get_count(frames->entries) == dx_get_limit(frames->entries)) -+ goto dxfull; -+ bh2 = ext3_append (handle, dir, &newblock, &retval); -+ if (!(bh2)) -+ goto dxfail2; -+ node2 = (struct dx_node *)(bh2->b_data); -+ entries2 = node2->entries; -+ node2->fake.rec_len = cpu_to_le16(sb->s_blocksize); -+ node2->fake.inode = 0; -+ BUFFER_TRACE(frame->bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, frame->bh); -+ if (levels) -+ { -+ unsigned icount1 = icount/2, icount2 = icount - icount1; -+ unsigned hash2 = dx_get_hash(entries + icount1); -+ dxtrace(printk("Split index %i/%i\n", icount1, icount2)); -+ -+ BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */ -+ ext3_journal_get_write_access(handle, frames[0].bh); -+ -+ memcpy ((char *) entries2, (char *) (entries + icount1), -+ icount2 * sizeof(struct dx_entry)); -+ dx_set_count (entries, icount1); -+ dx_set_count (entries2, icount2); -+ dx_set_limit (entries2, dx_node_limit(dir)); -+ -+ /* Which index block gets the new entry? */ -+ if (at - entries >= icount1) { -+ frame->at = at = at - entries - icount1 + entries2; -+ frame->entries = entries = entries2; -+ swap(frame->bh, bh2); - } -- -- ext3_debug ("creating next block\n"); -- -- BUFFER_TRACE(bh, "get_write_access"); -- ext3_journal_get_write_access(handle, bh); -- de = (struct ext3_dir_entry_2 *) bh->b_data; -- de->inode = 0; -- de->rec_len = le16_to_cpu(sb->s_blocksize); -- dir->u.ext3_i.i_disksize = -- dir->i_size = offset + sb->s_blocksize; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -- ext3_mark_inode_dirty(handle, dir); -+ dx_insert_block (frames + 0, hash2, newblock); -+ dxtrace(dx_show_index ("node", frames[1].entries)); -+ dxtrace(dx_show_index ("node", -+ ((struct dx_node *) bh2->b_data)->entries)); -+ ext3_journal_dirty_metadata(handle, bh2); -+ brelse (bh2); - } else { -- -- ext3_debug ("skipping to next block\n"); -- -- de = (struct ext3_dir_entry_2 *) bh->b_data; -+ dxtrace(printk("Creating second level index...\n")); -+ memcpy((char *) entries2, (char *) entries, -+ icount * sizeof(struct dx_entry)); -+ dx_set_limit(entries2, dx_node_limit(dir)); -+ -+ /* Set up root */ -+ dx_set_count(entries, 1); -+ dx_set_block(entries + 0, newblock); -+ ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1; -+ -+ /* Add new access path frame */ -+ frame = frames + 1; -+ frame->at = at = at - entries + entries2; -+ frame->entries = entries = entries2; -+ frame->bh = bh2; -+ ext3_journal_get_write_access(handle, frame->bh); - } -+ ext3_journal_dirty_metadata(handle, frames[0].bh); - } -- if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh, -- offset)) { -- brelse (bh); -- return -ENOENT; -- } -- if (ext3_match (namelen, name, de)) { -+ de = do_split(handle, dir, &bh, frame, hash, &retval); -+ dx_release (frames); -+ if (!(de)) -+ goto fail; -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ goto add; -+ -+dx_add: -+ dx_release (frames); -+ goto add; -+ -+dxfull: -+ ext3_warning(sb, __FUNCTION__, "Directory index full!\n"); -+ retval = -ENOSPC; -+dxfail2: -+ brelse(bh); -+dxfail1: -+ dx_release (frames); -+ goto fail1; -+ } -+ -+ blocks = dir->i_size >> sb->s_blocksize_bits; -+ for (block = 0, offset = 0; block < blocks; block++) { -+ bh = ext3_bread(handle, dir, block, 0, &retval); -+ if(!bh) -+ return retval; -+ de = (ext3_dirent *)bh->b_data; -+ top = bh->b_data + sb->s_blocksize - reclen; -+ while ((char *) de <= top) { -+ if (!ext3_check_dir_entry("ext3_add_entry", dir, de, -+ bh, offset)) { -+ brelse (bh); -+ return -EIO; -+ } -+ if (ext3_match(dentry->d_name.len,dentry->d_name.name,de)) { - brelse (bh); - return -EEXIST; -- } -- if ((le32_to_cpu(de->inode) == 0 && -- le16_to_cpu(de->rec_len) >= rec_len) || -- (le16_to_cpu(de->rec_len) >= -- EXT3_DIR_REC_LEN(de->name_len) + rec_len)) { -- BUFFER_TRACE(bh, "get_write_access"); -- ext3_journal_get_write_access(handle, bh); -- /* By now the buffer is marked for journaling */ -- offset += le16_to_cpu(de->rec_len); -- if (le32_to_cpu(de->inode)) { -- de1 = (struct ext3_dir_entry_2 *) ((char *) de + -- EXT3_DIR_REC_LEN(de->name_len)); -- de1->rec_len = -- cpu_to_le16(le16_to_cpu(de->rec_len) - -- EXT3_DIR_REC_LEN(de->name_len)); -- de->rec_len = cpu_to_le16( -- EXT3_DIR_REC_LEN(de->name_len)); -- de = de1; - } -- de->file_type = EXT3_FT_UNKNOWN; -- if (inode) { -- de->inode = cpu_to_le32(inode->i_ino); -- ext3_set_de_type(dir->i_sb, de, inode->i_mode); -- } else -- de->inode = 0; -- de->name_len = namelen; -- memcpy (de->name, name, namelen); -- /* -- * XXX shouldn't update any times until successful -- * completion of syscall, but too many callers depend -- * on this. -- * -- * XXX similarly, too many callers depend on -- * ext3_new_inode() setting the times, but error -- * recovery deletes the inode, so the worst that can -- * happen is that the times are slightly out of date -- * and/or different from the directory change time. -- */ -- dir->i_mtime = dir->i_ctime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -- dir->i_version = ++event; -- ext3_mark_inode_dirty(handle, dir); -- BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -- ext3_journal_dirty_metadata(handle, bh); -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ if ((de->inode ? rlen - nlen: rlen) >= reclen) -+ goto add; -+ de = (ext3_dirent *)((char *)de + rlen); -+ offset += rlen; -+ } -+ if (ext3_dx && blocks == 1 && test_opt(sb, INDEX)) -+ goto dx_make_index; -+ brelse(bh); -+ } -+ bh = ext3_append(handle, dir, &block, &retval); -+ if (!bh) -+ return retval; -+ de = (ext3_dirent *) bh->b_data; -+ de->inode = 0; -+ de->rec_len = cpu_to_le16(rlen = sb->s_blocksize); -+ nlen = 0; -+ goto add; -+ -+add: -+ BUFFER_TRACE(bh, "get_write_access"); -+ ext3_journal_get_write_access(handle, bh); -+ /* By now the buffer is marked for journaling */ -+ if (de->inode) { -+ ext3_dirent *de1 = (ext3_dirent *)((char *)de + nlen); -+ de1->rec_len = cpu_to_le16(rlen - nlen); -+ de->rec_len = cpu_to_le16(nlen); -+ de = de1; -+ } -+ de->file_type = EXT3_FT_UNKNOWN; -+ if (inode) { -+ de->inode = cpu_to_le32(inode->i_ino); -+ ext3_set_de_type(dir->i_sb, de, inode->i_mode); -+ } else -+ de->inode = 0; -+ de->name_len = dentry->d_name.len; -+ memcpy (de->name, dentry->d_name.name, dentry->d_name.len); -+ /* -+ * XXX shouldn't update any times until successful -+ * completion of syscall, but too many callers depend -+ * on this. -+ * -+ * XXX similarly, too many callers depend on -+ * ext3_new_inode() setting the times, but error -+ * recovery deletes the inode, so the worst that can -+ * happen is that the times are slightly out of date -+ * and/or different from the directory change time. -+ */ -+ dir->i_mtime = dir->i_ctime = CURRENT_TIME; -+ ext3_update_dx_flag(dir); -+ dir->i_version = ++event; -+ ext3_mark_inode_dirty(handle, dir); -+ BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -+ ext3_journal_dirty_metadata(handle, bh); -+ brelse(bh); -+ return 0; -+ -+dx_make_index: -+ { -+ struct buffer_head *bh2; -+ struct dx_root *root; -+ struct dx_frame frames[2], *frame; -+ struct dx_entry *entries; -+ ext3_dirent *de2; -+ char *data1; -+ unsigned len; -+ u32 hash; -+ -+ dxtrace(printk("Creating index\n")); -+ ext3_journal_get_write_access(handle, bh); -+ root = (struct dx_root *) bh->b_data; -+ -+ EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; -+ bh2 = ext3_append (handle, dir, &block, &retval); -+ if (!(bh2)) -+ { - brelse(bh); -- return 0; -+ return retval; - } -- offset += le16_to_cpu(de->rec_len); -- de = (struct ext3_dir_entry_2 *) -- ((char *) de + le16_to_cpu(de->rec_len)); -+ data1 = bh2->b_data; -+ -+ /* The 0th block becomes the root, move the dirents out */ -+ de = (ext3_dirent *) &root->info; -+ len = ((char *) root) + sb->s_blocksize - (char *) de; -+ memcpy (data1, de, len); -+ de = (ext3_dirent *) data1; -+ top = data1 + len; -+ while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top) -+ de = de2; -+ de->rec_len = cpu_to_le16(data1 + sb->s_blocksize - (char *)de); -+ /* Initialize the root; the dot dirents already exist */ -+ de = (ext3_dirent *) (&root->dotdot); -+ de->rec_len = cpu_to_le16(sb->s_blocksize-EXT3_DIR_REC_LEN(2)); -+ memset (&root->info, 0, sizeof(root->info)); -+ root->info.info_length = sizeof(root->info); -+ entries = root->entries; -+ dx_set_block (entries, 1); -+ dx_set_count (entries, 1); -+ dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info))); -+ -+ /* Initialize as for dx_probe */ -+ hash = dx_hash (dentry->d_name.name, dentry->d_name.len); -+ frame = frames; -+ frame->entries = entries; -+ frame->at = entries; -+ frame->bh = bh; -+ bh = bh2; -+ de = do_split(handle,dir, &bh, frame, hash, &retval); -+ dx_release (frames); -+ if (!(de)) -+ return retval; -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ goto add; - } -- brelse (bh); -- return -ENOSPC; -+fail1: -+ return retval; -+fail: -+ return -ENOENT; - } - - /* -@@ -451,7 +1212,8 @@ - struct inode * inode; - int err; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3); -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -478,7 +1240,8 @@ - struct inode *inode; - int err; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3); -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -507,7 +1270,8 @@ - if (dir->i_nlink >= EXT3_LINK_MAX) - return -EMLINK; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3); -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -550,7 +1320,7 @@ - if (err) - goto out_no_entry; - dir->i_nlink++; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(dir); - ext3_mark_inode_dirty(handle, dir); - d_instantiate(dentry, inode); - out_stop: -@@ -832,7 +1596,7 @@ - ext3_mark_inode_dirty(handle, inode); - dir->i_nlink--; - inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(dir); - ext3_mark_inode_dirty(handle, dir); - - end_rmdir: -@@ -878,7 +1642,7 @@ - if (retval) - goto end_unlink; - dir->i_ctime = dir->i_mtime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(dir); - ext3_mark_inode_dirty(handle, dir); - inode->i_nlink--; - if (!inode->i_nlink) -@@ -904,7 +1668,8 @@ - if (l > dir->i_sb->s_blocksize) - return -ENAMETOOLONG; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5); -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -959,7 +1724,8 @@ - if (inode->i_nlink >= EXT3_LINK_MAX) - return -EMLINK; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS); -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -995,7 +1761,8 @@ - - old_bh = new_bh = dir_bh = NULL; - -- handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2); -+ handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -@@ -1077,7 +1844,7 @@ - new_inode->i_ctime = CURRENT_TIME; - } - old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; -- old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(old_dir); - if (dir_bh) { - BUFFER_TRACE(dir_bh, "get_write_access"); - ext3_journal_get_write_access(handle, dir_bh); -@@ -1089,7 +1856,7 @@ - new_inode->i_nlink--; - } else { - new_dir->i_nlink++; -- new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(new_dir); - ext3_mark_inode_dirty(handle, new_dir); - } - } ---- ./include/linux/ext3_fs.h 2002/03/05 06:18:59 2.1 -+++ ./include/linux/ext3_fs.h 2002/03/05 06:26:56 -@@ -339,6 +339,7 @@ - #define EXT3_MOUNT_WRITEBACK_DATA 0x0C00 /* No data ordering */ - #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ - #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ -+#define EXT3_MOUNT_INDEX 0x4000 /* Enable directory index */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -575,6 +576,24 @@ - #define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) - #define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ - ~EXT3_DIR_ROUND) -+/* -+ * Hash Tree Directory indexing -+ * (c) Daniel Phillips, 2001 -+ */ -+ -+#define CONFIG_EXT3_INDEX -+ -+#ifdef CONFIG_EXT3_INDEX -+ enum {ext3_dx = 1}; -+ #define is_dx(dir) (EXT3_I(dir)->i_flags & EXT3_INDEX_FL) -+#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) -+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) -+#else -+ enum {ext3_dx = 0}; -+ #define is_dx(dir) 0 -+#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX) -+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2) -+#endif - - #ifdef __KERNEL__ - /* ---- ./include/linux/ext3_jbd.h 2002/03/05 06:18:59 2.1 -+++ ./include/linux/ext3_jbd.h 2002/03/05 06:33:54 -@@ -63,6 +63,8 @@ - - #define EXT3_RESERVE_TRANS_BLOCKS 12 - -+#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 -+ - int - ext3_mark_iloc_dirty(handle_t *handle, - struct inode *inode, diff --git a/lustre/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 4c8fb86..0000000 --- a/lustre/extN/linux-2.4.18ea-0.8.26.diff +++ /dev/null @@ -1,1769 +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 -@@ -435,6 +435,7 @@ static int ext3_add_nondir(handle_t *han - return 0; - } - } -+ ext3_xattr_drop_inode(handle, inode); - ext3_dec_count(handle, inode); - iput(inode); - return err; -@@ -514,7 +519,7 @@ - if (IS_SYNC(dir)) - handle->h_sync = 1; - -- inode = ext3_new_inode (handle, dir, S_IFDIR); -+ inode = ext3_new_inode (handle, dir, S_IFDIR | mode); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; -@@ -522,7 +527,6 @@ - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; -- inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize; -- inode->i_blocks = 0; -+ inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; - dir_block = ext3_bread (handle, inode, 0, 1, &err); - if (!dir_block) { - inode->i_nlink--; /* is this nlink == 0? */ -@@ -549,9 +553,6 @@ - BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata"); - ext3_journal_dirty_metadata(handle, dir_block); - brelse (dir_block); -- inode->i_mode = S_IFDIR | mode; -- if (dir->i_mode & S_ISGID) -- inode->i_mode |= S_ISGID; - ext3_mark_inode_dirty(handle, inode); - err = ext3_add_entry (handle, dentry, inode); - if (err) -@@ -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/extN/patch-2.4.18-chaos22 b/lustre/extN/patch-2.4.18-chaos22 deleted file mode 100644 index c40d4ea..0000000 --- a/lustre/extN/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/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/liblustre.h b/lustre/include/liblustre.h deleted file mode 100644 index 0b37021..0000000 --- a/lustre/include/liblustre.h +++ /dev/null @@ -1,431 +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. - * - * User-space Lustre headers. - * - */ -#ifndef LIBLUSTRE_H__ -#define LIBLUSTRE_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* definitions for liblustre */ - -/* always adopt 2.5 definitions */ -#define LINUX_VERSION_CODE 1 -#define KERNEL_VERSION(a,b,c) 0 - -static inline void inter_module_put(void *a) -{ - return; -} - -extern ptl_handle_ni_t tcpnal_ni; - -static inline void *inter_module_get(char *arg) -{ - - if (strcmp(arg, "tcpnal_ni") == 0 ) - return &tcpnal_ni; - else - return NULL; - -} - - -/* cheats for now */ - -struct work_struct { - void (*ws_task)(void *arg); - void *ws_arg; -}; - -static inline void prepare_work(struct work_struct *q, void (*t)(void *), - void *arg) -{ - q->ws_task = t; - q->ws_arg = arg; - return; -} - -static inline void schedule_work(struct work_struct *q) -{ - q->ws_task(q->ws_arg); -} - - -#define strnlen(a,b) strlen(a) -static inline void *kmalloc(int size, int prot) -{ - return malloc(size); -} -#define vmalloc malloc -#define vfree free -#define kfree(a) free(a) -#define GFP_KERNEL 1 -#define GFP_HIGHUSER 1 -#define IS_ERR(a) (abs((int)(a)) < 500 ? 1 : 0) -#define PTR_ERR(a) ((int)(a)) - -#define capable(foo) 1 -#define CAP_SYS_ADMIN 1 - -typedef struct { - void *cwd; - -}mm_segment_t; - -typedef void *read_proc_t; -typedef void *write_proc_t; - - -/* modules */ - -struct module { - int count; -}; - -static inline void MODULE_AUTHOR(char *name) -{ - printf("%s\n", name); -} -#define MODULE_DESCRIPTION(name) MODULE_AUTHOR(name) -#define MODULE_LICENSE(name) MODULE_AUTHOR(name) - -#define THIS_MODULE NULL -#define __init -#define __exit - -/* devices */ - -static inline int misc_register(void *foo) -{ - return 0; -} -#define misc_deregister misc_register - -#define __MOD_INC_USE_COUNT(m) do {int a = 1; a++; } while (0) -#define __MOD_DEC_USE_COUNT(m) do {int a = 1; a++; } while (0) -#define MOD_INC_USE_COUNT do {int a = 1; a++; } while (0) -#define MOD_DEC_USE_COUNT do {int a = 1; a++; } while (0) - -/* module initialization */ -extern int init_obdclass(void); -extern int ptlrpc_init(void); -extern int ldlm_init(void); -extern int osc_init(void); -extern int lov_init(void); -extern int echo_client_init(void); - - - -/* general stuff */ -#define jiffies 0 - -#define EXPORT_SYMBOL(S) - -typedef int spinlock_t; -typedef __u64 kdev_t; - -#define SPIN_LOCK_UNLOCKED 0 -#define spin_lock(l) do {int a = 1; a++; } while (0) -#define spin_unlock(l) do {int a= 1; a++; } while (0) -#define spin_lock_init(l) do {int a= 1; a++; } while (0) -static inline void spin_lock_bh(spinlock_t *l) -{ - return; -} -static inline void spin_unlock_bh(spinlock_t *l) -{ - return; -} -static inline void spin_lock_irqrestore(a,b) -{ - return; -} -static inline void spin_unlock_irqrestore(a,b) -{ - return; -} -static inline void spin_lock_irqsave(a,b) -{ - return; -} - -#define barrier() do {int a= 1; a++; } while (0) - -/* registering symbols */ - -#define ERESTARTSYS ERESTART -#define HZ 1 - -/* random */ - -static inline void get_random_bytes(void *ptr, int size) -{ - static int r; - int *p = (int *)ptr; - int *end = p + (size / sizeof(int)); - r = rand(); - while ( p + sizeof(int) < end ) { - *p = r; - p++; - } -} - -/* memory */ - -static inline int copy_from_user(void *a,void *b, int c) -{ - memcpy(a,b,c); - return 0; -} - -static inline int copy_to_user(void *a,void *b, int c) -{ - memcpy(a,b,c); - return 0; -} - - -/* slabs */ -typedef struct { - int size; -} kmem_cache_t; -#define SLAB_HWCACHE_ALIGN 0 -static inline kmem_cache_t *kmem_cache_create(name,objsize,cdum,d,e,f) -{ - kmem_cache_t *c; - c = malloc(sizeof(*c)); - if (!c) - return NULL; - c->size = objsize; - return c; -}; - -static inline int kmem_cache_destroy(kmem_cache_t *a) -{ - free(a); - return 0; -} -#define kmem_cache_validate(a,b) 1 -#define kmem_cache_alloc(cache, prio) malloc(cache->size) -#define kmem_cache_free(cache, obj) OBD_FREE(obj, cache->size) -#define PORTAL_SLAB_ALLOC(lock,cache,size) do { lock = kmem_cache_alloc(cache,prio); } while (0) -#define PORTAL_SLAB_FREE(lock,cache,size) do { lock = kmem_cache_alloc(cache,prio); } while (0) - -struct page { - void *addr; - int index; -}; - -#define kmap(page) (page)->addr -#define kunmap(a) do { int foo = 1; foo++; } while (0) - -static inline struct page *alloc_pages(mask,foo) -{ - struct page *pg = malloc(sizeof(*pg)); - - if (!pg) - return NULL; -#ifdef MAP_ANONYMOUS - pg->addr = mmap(0, PAGE_SIZE, PROT_WRITE, MAP_ANONYMOUS, 0, 0); -#else - pg->addr = malloc(PAGE_SIZE); -#endif - - if (!pg->addr) { - free(pg); - return NULL; - } - return pg; -} - -static inline void __free_pages(struct page *pg, int what) -{ -#ifdef MAP_ANONYMOUS - munmap(pg->addr, PAGE_SIZE); -#else - free(pg->addr); -#endif - free(pg); -} - -/* arithmetic */ -#define do_div(a,b) (a)/(b) - -/* dentries / intents */ -struct lookup_intent { - void *it_iattr; -}; - -struct iattr { - int mode; -}; - -struct dentry { - int d_count; -}; -struct file { - struct dentry *f_dentry; - void *private_data; -} ; - -struct vfsmount { - void *pwd; -}; -#define cpu_to_le32(x) ((__u32)(x)) - -/* semaphores */ -struct semaphore { - int count; -}; - -#define down(a) do {(a)->count++;} while (0) -#define up(a) do {(a)->count--;} while (0) -#define sema_init(a,b) do { (a)->count = b; } while (0) - -typedef struct { - struct list_head sleepers; -} wait_queue_head_t; - -typedef struct { - struct list_head sleeping; - void *process; -} wait_queue_t; - -struct signal { - int signal; -}; - -struct task_struct { - int state; - struct signal pending; - char comm[32]; - int pid; -}; - -extern struct task_struct *current; - - - -#define set_current_state(foo) do { current->state = foo; } while (0) - -#define init_waitqueue_entry(q,p) do { (q)->process = p; } while (0) -#define add_wait_queue(q,p) do { list_add(&(q)->sleepers, &(p)->sleeping); } while (0) -#define del_wait_queue(p) do { list_del(&(p)->sleeping); } while (0) -#define remove_wait_queue(q,p) do { list_del(&(p)->sleeping); } while (0) - -#define init_waitqueue_head(l) INIT_LIST_HEAD(&(l)->sleepers) -#define wake_up(l) do { int a; a++; } while (0) -#define wait_event(l,m) do { int a; a++; } while (0) -#define TASK_INTERRUPTIBLE 0 -#define TASK_UNINTERRUPTIBLE 1 -#define TASK_RUNNING 2 - - -#define schedule() do { int a; a++; } while (0) -static inline int schedule_timeout(t) -{ - return 0; -} - -#define lock_kernel() do { int a; a++; } while (0) -#define daemonize(l) do { int a; a++; } while (0) -#define sigfillset(l) do { int a; a++; } while (0) -#define recalc_sigpending(l) do { int a; a++; } while (0) -#define kernel_thread(l,m,n) - -static inline int call_usermodehelper(char *prog, char **argv, char **evnp) -{ - return 0; -} - - - -#define KERN_INFO - - - -struct timer_list { - struct list_head tl_list; - void (*function)(unsigned long unused); - void *data; - int expires; -}; - -static inline int timer_pending(struct timer_list *l) -{ - if (l->expires > jiffies) - return 1; - else - return 0; -} - -static inline int init_timer(struct timer_list *l) -{ - INIT_LIST_HEAD(&l->tl_list); - return 0; -} - -static inline void mod_timer(struct timer_list *l, int thetime) -{ - l->expires = thetime; -} - -static inline void del_timer(struct timer_list *l) -{ - free(l); -} - -typedef struct { volatile int counter; } atomic_t; - -#define atomic_read(a) ((a)->counter) -#define atomic_set(a,b) do {(a)->counter = b; } while (0) -#define atomic_dec_and_test(a) ((--((a)->counter)) == 0) -#define atomic_inc(a) (((a)->counter)++) -#define atomic_dec(a) do { (a)->counter--; } while (0) -#define atomic_add(b,a) do {(a)->counter += b;} while (0) -#define atomic_sub(b,a) do {(a)->counter -= b;} while (0) - -#define LBUG() do { sleep(1000000); } while (0) - -#include -#include -#include -#include -#include -#include - - -#endif - 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 cd8f12b..0000000 --- a/lustre/include/linux/lprocfs_status.h +++ /dev/null @@ -1,187 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Top level header file for LProc SNMP - * Author: Hariharan Thantry thantry@users.sourceforge.net - */ -#ifndef _LPROCFS_SNMP_H -#define _LPROCFS_SNMP_H - -#ifdef __KERNEL__ -#include -#include -#endif - -#ifndef LPROCFS -#ifdef CONFIG_PROC_FS /* Ensure that /proc is configured */ -#define LPROCFS -#endif -#endif - -struct lprocfs_vars { - char *name; - read_proc_t *read_fptr; - write_proc_t *write_fptr; - void *data; -}; - -struct lprocfs_static_vars { - struct lprocfs_vars *module_vars; - struct lprocfs_vars *obd_vars; -}; - -/* class_obd.c */ -extern struct proc_dir_entry *proc_lustre_root; - - -#define LPROCFS_INIT_MULTI_VARS(array, size) \ -void lprocfs_init_multi_vars(unsigned int idx, \ - struct lprocfs_static_vars *x) \ -{ \ - struct lprocfs_static_vars *glob = (struct lprocfs_static_vars*)array; \ - LASSERT(glob != 0); \ - LASSERT(idx < (unsigned int)(size)); \ - x->module_vars = glob[idx].module_vars; \ - x->obd_vars = glob[idx].obd_vars; \ -} \ - -#ifdef LPROCFS -#define LPROCFS_INIT_VARS(vclass, vinstance) \ -void lprocfs_init_vars(struct lprocfs_static_vars *x) \ -{ \ - x->module_vars = vclass; \ - x->obd_vars = vinstance; \ -} \ - -extern void lprocfs_init_vars(struct lprocfs_static_vars *var); -extern void lprocfs_init_multi_vars(unsigned int idx, - struct lprocfs_static_vars *var); -/* lprocfs_status.c */ -extern int lprocfs_add_vars(struct proc_dir_entry *root, - struct lprocfs_vars *var, - void *data); - -extern struct proc_dir_entry *lprocfs_register(const char *name, - struct proc_dir_entry *parent, - struct lprocfs_vars *list, - void *data); - -extern void lprocfs_remove(struct proc_dir_entry *root); - -struct obd_device; -extern int lprocfs_obd_attach(struct obd_device *dev, struct lprocfs_vars *list); -extern int lprocfs_obd_detach(struct obd_device *dev); - -/* Generic callbacks */ - -extern int lprocfs_rd_u64(char *page, char **start, off_t off, - int count, int *eof, void *data); -extern int lprocfs_rd_uuid(char *page, char **start, off_t off, - int count, int *eof, void *data); -extern int lprocfs_rd_name(char *page, char **start, off_t off, - int count, int *eof, void *data); -extern int lprocfs_rd_server_uuid(char *page, char **start, off_t off, - int count, int *eof, void *data); -extern int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, - int count, int *eof, void *data); -extern int lprocfs_rd_numrefs(char *page, char **start, off_t off, - int count, int *eof, void *data); - -/* Statfs helpers */ -struct statfs; -extern int lprocfs_rd_blksize(char *page, char **start, off_t off, - int count, int *eof, struct statfs *sfs); -extern int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, - int count, int *eof, struct statfs *sfs); -extern int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, - int count, int *eof, struct statfs *sfs); -extern int lprocfs_rd_filestotal(char *page, char **start, off_t off, - int count, int *eof, struct statfs *sfs); -extern int lprocfs_rd_filesfree(char *page, char **start, off_t off, - int count, int *eof, struct statfs *sfs); -extern int lprocfs_rd_filegroups(char *page, char **start, off_t off, - int count, int *eof, struct statfs *sfs); - -#define DEFINE_LPROCFS_STATFS_FCT(fct_name, get_statfs_fct) \ -int fct_name(char *page, char **start, off_t off, \ - int count, int *eof, void *data) \ -{ \ - struct statfs sfs; \ - int rc = get_statfs_fct((struct obd_device*)data, &sfs); \ - return (rc==0 \ - ? lprocfs_##fct_name (page, start, off, count, eof, &sfs) \ - : rc); \ -} - -#else - -static inline struct proc_dir_entry * -lprocfs_register(const char *name, struct proc_dir_entry *parent, - struct lprocfs_vars *list, void *data) { return NULL; } -static inline void lprocfs_init_vars(struct lprocfs_static_vars *x) { return; } -static inline int lprocfs_add_vars(struct proc_dir_entry *root, - struct lprocfs_vars *var, - void *data) { return 0; } -static inline void lprocfs_remove(struct proc_dir_entry *root) {}; -struct obd_device; -static inline int lprocfs_obd_attach(struct obd_device *dev, - struct lprocfs_vars *list) { return 0; } -static inline int lprocfs_obd_detach(struct obd_device *dev) { return 0; } -static inline int lprocfs_rd_u64(char *page, char **start, off_t off, - int count, int *eof, void *data) { return 0; } -static inline int lprocfs_rd_uuid(char *page, char **start, off_t off, - int count, int *eof, void *data) { return 0; } -static inline int lprocfs_rd_name(char *page, char **start, off_t off, - int count, int *eof, void *data) { return 0; } -static inline int lprocfs_rd_server_uuid(char *page, char **start, off_t off, - int count, int *eof, void *data) { return 0; } -static inline int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, - int count, int *eof, void *data) { return 0; } -static inline int lprocfs_rd_numrefs(char *page, char **start, off_t off, - int count, int *eof, void *data) { return 0; } - -/* Statfs helpers */ -struct statfs; -static inline -int lprocfs_rd_blksize(char *page, char **start, off_t off, - int count, int *eof, struct statfs *sfs) { return 0; } -static inline -int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, - int count, int *eof, struct statfs *sfs) { return 0; } -static inline -int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, - int count, int *eof, struct statfs *sfs) { return 0; } -static inline -int lprocfs_rd_filestotal(char *page, char **start, off_t off, - int count, int *eof, struct statfs *sfs) { return 0; } -static inline -int lprocfs_rd_filesfree(char *page, char **start, off_t off, - int count, int *eof, struct statfs *sfs) { return 0; } -static inline -int lprocfs_rd_filegroups(char *page, char **start, off_t off, - int count, int *eof, struct statfs *sfs) { return 0; } - -#define DEFINE_LPROCFS_STATFS_FCT(fct_name, get_statfs_fct) \ -int fct_name(char *page, char **start, off_t off, \ - int count, int *eof, void *data) { *eof = 1; return 0; } - -#endif /* LPROCFS */ - -#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 c120225..0000000 --- a/lustre/include/linux/lustre_dlm.h +++ /dev/null @@ -1,483 +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 -#endif - -#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_LOCK_REPLACED = 302, - - 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 */ -#define LDLM_FL_LOCAL (1 << 14) // a local lock (ie, no srv/cli split) - -/* 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, - int flag); -typedef int (*ldlm_completion_callback)(struct ldlm_lock *lock, int flags, void *data); -typedef int (*ldlm_granted_callback)(struct ldlm_lock *, - struct lustre_msg *, int offset); - -struct ldlm_lock { - struct portals_handle l_handle; // must be first in the structure - 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; - ldlm_granted_callback l_granted_cb; - - struct obd_export *l_export; - struct lustre_handle *l_connh; - __u32 l_flags; - struct lustre_handle l_remote_handle; - void *l_data; - void *l_cp_data; - 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_namespace *, struct ldlm_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 - -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; - struct ldlm_res_id lr_name; - __u32 lr_version[RES_VERSION_SIZE]; - atomic_t lr_refcount; - - /* lr_tmp holds a list head temporarily, during the building of a work - * queue. see ldlm_add_ast_work_item and ldlm_run_ast_work */ - 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; /* protected by namespace lock */ - struct obd_import led_import; -}; - -extern struct obd_ops ldlm_obd_ops; - -extern char *ldlm_lockname[]; -extern char *ldlm_typename[]; -extern char *ldlm_it2str(int it); - -#define __LDLM_DEBUG(level, lock, format, a...) \ -do { \ - if (lock->l_resource == NULL) { \ - CDEBUG(level, "### " format \ - " ns: \?\? lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "\ - "res: \?\? rrc=\?\? type: \?\?\? remote: "LPX64")\n" \ - , ## a, lock, lock->l_handle.h_cookie, \ - atomic_read(&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.cookie); \ - break; \ - } \ - if (lock->l_resource->lr_type == LDLM_EXTENT) { \ - CDEBUG(level, "### " format \ - " ns: %s lock: %p/"LPX64" 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_handle.h_cookie, atomic_read(&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.name[0], \ - lock->l_resource->lr_name.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.cookie); \ - break; \ - } \ - { \ - CDEBUG(level, "### " format \ - " ns: %s lock: %p/"LPX64" 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_handle.h_cookie, \ - atomic_read (&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.name[0], \ - lock->l_resource->lr_name.name[1], \ - atomic_read(&lock->l_resource->lr_refcount), \ - ldlm_typename[lock->l_resource->lr_type], \ - lock->l_remote_handle.cookie); \ - } \ -} while (0) - -#define LDLM_DEBUG(lock, format, a...) __LDLM_DEBUG(D_DLMTRACE, lock, \ - format, ## a) -#define LDLM_ERROR(lock, format, a...) __LDLM_DEBUG(D_ERROR, lock, format, ## a) - -#define LDLM_DEBUG_NOLOCK(format, a...) \ - CDEBUG(D_DLMTRACE, "### " format "\n" , ## a) - -/* - * Iterators. - */ - -#define LDLM_ITER_CONTINUE 1 /* keep iterating */ -#define LDLM_ITER_STOP 0 /* stop iterating */ - -typedef int (*ldlm_iterator_t)(struct ldlm_lock *, void *); -typedef int (*ldlm_res_iterator_t)(struct ldlm_resource *, 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_namespace_foreach_res(struct ldlm_namespace *ns, - ldlm_res_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_namespace *, struct ldlm_lock **, void *, - ldlm_mode_t, int flags, void *); - -/* ldlm_lockd.c */ -int ldlm_server_blocking_ast(struct ldlm_lock *, struct ldlm_lock_desc *, - void *data, int flag); -int ldlm_server_completion_ast(struct ldlm_lock *lock, int flags, void *data); -int ldlm_handle_enqueue(struct ptlrpc_request *req, ldlm_completion_callback, - ldlm_blocking_callback); -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(ldlm_res_policy arg); -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 flags); -void ldlm_cancel_callback(struct ldlm_lock *); -int ldlm_lock_set_data(struct lustre_handle *, void *data, void *cp_data); -void ldlm_lock_remove_from_lru(struct ldlm_lock *); - -static inline struct ldlm_lock *ldlm_handle2lock(struct lustre_handle *h) -{ - return __ldlm_handle2lock(h, 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_lock_decref_and_cancel(struct lustre_handle *lockh, __u32 mode); -void ldlm_grant_lock(struct ldlm_lock *lock, void *data, int datalen); -int ldlm_lock_match(struct ldlm_namespace *ns, int flags, struct ldlm_res_id *, - __u32 type, void *cookie, int cookielen, ldlm_mode_t mode, - struct lustre_handle *); -struct ldlm_lock * -ldlm_lock_create(struct ldlm_namespace *ns, - struct lustre_handle *parent_lock_handle, struct ldlm_res_id, - __u32 type, ldlm_mode_t mode, void *data, void *cp_data); -ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *, struct ldlm_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); -int ldlm_run_ast_work(struct list_head *rpc_list); -void ldlm_reprocess_all(struct ldlm_resource *res); -void ldlm_reprocess_all_ns(struct ldlm_namespace *ns); -void ldlm_lock_dump(int level, struct ldlm_lock *lock); -void ldlm_lock_dump_handle(int level, struct lustre_handle *); - -/* 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, - struct ldlm_res_id, __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_namespace *, struct ldlm_lock *, - struct ldlm_res_id); - -/* ldlm_request.c */ -int ldlm_expired_completion_wait(void *data); -int ldlm_completion_ast(struct ldlm_lock *lock, int flags, void *data); -int ldlm_cli_enqueue(struct lustre_handle *conn, - struct ptlrpc_request *req, - struct ldlm_namespace *ns, - struct lustre_handle *parent_lock_handle, - struct ldlm_res_id, - __u32 type, - void *cookie, int cookielen, - ldlm_mode_t mode, - int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback callback, - void *data, - void *cp_data, - 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, - struct ldlm_res_id, - __u32 type, - void *cookie, int cookielen, - ldlm_mode_t mode, - int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback callback, - void *data, - void *cp_data, - 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 *, struct ldlm_res_id *, - 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, int flag); - - -/* 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 694bd3e..0000000 --- a/lustre/include/linux/lustre_export.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 __EXPORT_H -#define __EXPORT_H - -#include -#include -#include -#include - -struct lov_export_data { - spinlock_t led_lock; - struct list_head led_open_head; -}; - -struct ec_export_data { /* echo client */ - struct list_head eced_open_head; - struct list_head eced_locks; -}; - -struct obd_export { - __u64 exp_cookie; - struct obd_uuid exp_client_uuid; - 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; - struct ec_export_data eu_ec_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 -#define exp_ec_data u.eu_ec_data - -extern struct obd_export *class_conn2export(struct lustre_handle *conn); -extern struct obd_device *class_conn2obd(struct lustre_handle *conn); - -#endif /* __EXPORT_H */ diff --git a/lustre/include/linux/lustre_fsfilt.h b/lustre/include/linux/lustre_fsfilt.h deleted file mode 100644 index 6b0cbfa..0000000 --- a/lustre/include/linux/lustre_fsfilt.h +++ /dev/null @@ -1,170 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2001 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Filesystem interface helper. - * - */ - -#ifndef _LUSTRE_FSFILT_H -#define _LUSTRE_FSFILT_H - -#ifdef __KERNEL__ - -#include -#include - -typedef void (*fsfilt_cb_t)(struct obd_device *obd, __u64 last_rcvd, int error); - -struct fsfilt_objinfo { - struct dentry *fso_dentry; - int fso_bufcnt; -}; - -struct fsfilt_operations { - struct list_head fs_list; - struct module *fs_owner; - char *fs_type; - void *(* fs_start)(struct inode *inode, int op); - void *(* fs_brw_start)(int objcount, struct fsfilt_objinfo *fso, - int niocount, struct niobuf_remote *nb); - int (* fs_commit)(struct inode *inode, void *handle); - int (* fs_setattr)(struct dentry *dentry, void *handle, - struct iattr *iattr); - int (* fs_set_md)(struct inode *inode, void *handle, void *md, - int size); - int (* fs_get_md)(struct inode *inode, void *md, int size); - ssize_t (* fs_readpage)(struct file *file, char *buf, size_t count, - loff_t *offset); - int (* fs_journal_data)(struct file *file); - int (* fs_set_last_rcvd)(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func); - int (* fs_statfs)(struct super_block *sb, struct obd_statfs *osfs); - int (* fs_sync)(struct super_block *sb); - int (* fs_prep_san_write)(struct inode *inode, long *blocks, - int nblocks, loff_t newsize); -}; - -extern int fsfilt_register_ops(struct fsfilt_operations *fs_ops); -extern void fsfilt_unregister_ops(struct fsfilt_operations *fs_ops); -extern struct fsfilt_operations *fsfilt_get_ops(char *type); -extern void fsfilt_put_ops(struct fsfilt_operations *fs_ops); - -#define FSFILT_OP_UNLINK 1 -#define FSFILT_OP_RMDIR 2 -#define FSFILT_OP_RENAME 3 -#define FSFILT_OP_CREATE 4 -#define FSFILT_OP_MKDIR 5 -#define FSFILT_OP_SYMLINK 6 -#define FSFILT_OP_MKNOD 7 -#define FSFILT_OP_SETATTR 8 -#define FSFILT_OP_LINK 9 - -static inline void *fsfilt_start(struct obd_device *obd, - struct inode *inode, int op) -{ - ENTRY; - return obd->obd_fsops->fs_start(inode, op); -} - -static inline void *fsfilt_brw_start(struct obd_device *obd, int objcount, - struct fsfilt_objinfo *fso, int niocount, - struct niobuf_remote *nb) -{ - return obd->obd_fsops->fs_brw_start(objcount, fso, niocount, nb); -} - -static inline int fsfilt_commit(struct obd_device *obd, struct inode *inode, - void *handle) -{ - return obd->obd_fsops->fs_commit(inode, handle); - EXIT; -} - -static inline int fsfilt_setattr(struct obd_device *obd, struct dentry *dentry, - void *handle, struct iattr *iattr) -{ - int rc; - /* - * NOTE: we probably don't need to take i_sem here when changing - * ATTR_SIZE because the MDS never needs to truncate a file. - * The ext2/ext3 code never truncates a directory, and files - * stored on the MDS are entirely sparse (no data blocks). - * If we do need to get it, we can do it here. - */ - lock_kernel(); - rc = obd->obd_fsops->fs_setattr(dentry, handle, iattr); - unlock_kernel(); - - return rc; -} - -static inline int fsfilt_set_md(struct obd_device *obd, struct inode *inode, - void *handle, void *md, int size) -{ - return obd->obd_fsops->fs_set_md(inode, handle, md, size); -} - -static inline int fsfilt_get_md(struct obd_device *obd, struct inode *inode, - void *md, int size) -{ - return obd->obd_fsops->fs_get_md(inode, md, size); -} - -static inline ssize_t fsfilt_readpage(struct obd_device *obd, - struct file *file, char *buf, - size_t count, loff_t *offset) -{ - return obd->obd_fsops->fs_readpage(file, buf, count, offset); -} - -static inline int fsfilt_journal_data(struct obd_device *obd, struct file *file) -{ - return obd->obd_fsops->fs_journal_data(file); -} - -static inline int fsfilt_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func) -{ - return obd->obd_fsops->fs_set_last_rcvd(obd, last_rcvd,handle,cb_func); -} - -static inline int fsfilt_statfs(struct obd_device *obd, struct super_block *fs, - struct obd_statfs *osfs) -{ - return obd->obd_fsops->fs_statfs(fs, osfs); -} - -static inline int fsfilt_sync(struct obd_device *obd, struct super_block *fs) -{ - return obd->obd_fsops->fs_sync(fs); -} - -static inline int fs_prep_san_write(struct obd_device *obd, - struct inode *inode, - long *blocks, - int nblocks, - loff_t newsize) -{ - return obd->obd_fsops->fs_prep_san_write(inode, blocks, - nblocks, newsize); -} -#endif /* __KERNEL__ */ - -#endif diff --git a/lustre/include/linux/lustre_ha.h b/lustre/include/linux/lustre_ha.h deleted file mode 100644 index 87b0bf3..0000000 --- a/lustre/include/linux/lustre_ha.h +++ /dev/null @@ -1,64 +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 -#define PTLRPC_RECOVD_PHASE_NOTCONN 4 - -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; -struct ptlrpc_request; - -int ptlrpc_run_recovery_upcall(struct ptlrpc_connection *conn); -int ptlrpc_reconnect_import(struct obd_import *imp, int rq_opc, - struct ptlrpc_request **reqptr); -int ptlrpc_replay(struct obd_import *imp); -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_handles.h b/lustre/include/linux/lustre_handles.h deleted file mode 100644 index f644cf1..0000000 --- a/lustre/include/linux/lustre_handles.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __LINUX_HANDLES_H_ -#define __LINUX_HANDLES_H_ - -#ifdef __KERNEL__ -#include -#include -#include -#endif - -typedef void (*portals_handle_addref_cb)(void *object); - -/* These handles are most easily used by having them appear at the very top of - * whatever object that you want to make handles for. ie: - * - * struct ldlm_lock { - * struct portals_handle handle; - * ... - * }; - * - * Now you're able to assign the results of cookie2handle directly to an - * ldlm_lock. If it's not at the top, you'll want to hack up a macro that - * uses some offsetof() magic. */ - -struct portals_handle { - struct list_head h_link; - __u64 h_cookie; - portals_handle_addref_cb h_addref; -}; - -/* handles.c */ - -/* Add a handle to the hash table */ -void class_handle_hash(struct portals_handle *, portals_handle_addref_cb); -void class_handle_unhash(struct portals_handle *); -void *class_handle2object(__u64 cookie); -int class_handle_init(void); -void class_handle_cleanup(void); - -#endif diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h deleted file mode 100644 index 3ef86ac..0000000 --- a/lustre/include/linux/lustre_idl.h +++ /dev/null @@ -1,624 +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 -# include /* for strncpy, below */ -#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 - */ -struct obd_uuid { - __u8 uuid[37]; -}; - -static inline void obd_str2uuid(struct obd_uuid *uuid, char *tmp) -{ - strncpy(uuid->uuid, tmp, sizeof(*uuid)); - uuid->uuid[sizeof(*uuid) - 1] = '\0'; -} - -/* 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 PTLBD_REQUEST_PORTAL 19 -#define PTLBD_REPLY_PORTAL 20 -#define PTLBD_BULK_PORTAL 21 -#define MDS_SETATTR_PORTAL 22 -#define MDS_READPAGE_PORTAL 23 - -#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 -#define MSG_RESENT 2 - -static inline int lustre_msg_get_flags(struct lustre_msg *msg) -{ - return (msg->flags & MSG_GEN_FLAG_MASK); -} - -static inline void lustre_msg_add_flags(struct lustre_msg *msg, int flags) -{ - msg->flags |= MSG_GEN_FLAG_MASK & flags; -} - -static inline void lustre_msg_set_flags(struct lustre_msg *msg, int flags) -{ - msg->flags &= ~MSG_GEN_FLAG_MASK; - lustre_msg_add_flags(msg, 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_add_op_flags(struct lustre_msg *msg, int flags) -{ - msg->flags |= ((flags & MSG_GEN_FLAG_MASK) << MSG_OP_FLAG_SHIFT); -} - -static inline void lustre_msg_set_op_flags(struct lustre_msg *msg, int flags) -{ - msg->flags &= ~MSG_OP_FLAG_MASK; - lustre_msg_add_op_flags(msg, flags); -} - -/* - * Flags for all connect opcodes (MDS_CONNECT, OST_CONNECT) - */ - -#define MSG_CONNECT_RECOVERING 0x1 -#define MSG_CONNECT_RECONNECT 0x2 -#define MSG_CONNECT_REPLAYABLE 0x4 - -/* - * 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 -#define OST_SAN_READ 14 -#define OST_SAN_WRITE 15 -#define OST_SYNCFS 16 - - -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 -#define FD_OSTDATA_SIZE 32 -#if (FD_OSTDATA_SIZE > OBD_INLINESZ) -# error FD_OSTDATA_SIZE must be smaller than OBD_INLINESZ -#endif - -/* 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; - __u64 lmm_object_id; /* lov object id */ - __u32 lmm_stripe_size; /* size of the stripe */ - __u32 lmm_stripe_offset; /* starting stripe offset in lmm_objects */ - __u16 lmm_stripe_count; /* number of stipes in use for this object */ - __u16 lmm_ost_count; /* how many OST idx are in this LOV md */ - 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_FLCKSUM (0x00100000) /* bulk data checksum */ -#define OBD_MD_FLNOTOBD (~(OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS | OBD_MD_LINKNAME|\ - OBD_MD_FLEASIZE | OBD_MD_FLHANDLE | OBD_MD_FLCKSUM)) - -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; - __u32 ioo_type; - __u32 ioo_bufcnt; -}; - -struct niobuf_remote { - __u64 offset; - __u32 len; - __u32 xid; - __u32 flags; -} __attribute__((packed)); - -/* request structure for OST's */ - -#define OST_REQ_HAS_OA1 0x1 - -struct ost_body { - struct obdo oa; -}; - -/* - * MDS REQ RECORDS - */ - -/* opcodes */ -#define MDS_GETATTR 33 -#define MDS_GETATTR_NAME 34 -#define MDS_CLOSE 35 -#define MDS_REINT 36 -#define MDS_READPAGE 37 -#define MDS_CONNECT 38 -#define MDS_DISCONNECT 39 -#define MDS_GETSTATUS 40 -#define MDS_STATFS 41 -#define MDS_GETLOVINFO 42 -/* - * Do not exceed 63 - */ - -#define REINT_SETATTR 1 -#define REINT_CREATE 2 -#define REINT_LINK 3 -#define REINT_UNLINK 4 -#define REINT_RENAME 5 -#define REINT_OPEN 6 -#define REINT_MAX 6 - -#define IT_INTENT_EXEC 1 -#define IT_OPEN_LOOKUP (1 << 1) -#define IT_OPEN_NEG (1 << 2) -#define IT_OPEN_POS (1 << 3) -#define IT_OPEN_CREATE (1 << 4) -#define IT_OPEN_OPEN (1 << 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; - __u64 blocks; /* XID, in the case of MDS_READPAGE */ - __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; - __u32 suppgid; -}; - -/* 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; - __u32 sa_suppgid; -}; - -struct mds_rec_create { - __u32 cr_opcode; - __u32 cr_fsuid; - __u32 cr_fsgid; - __u32 cr_cap; - __u32 cr_flags; /* for use with open */ - __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; - __u32 cr_suppgid; -}; - -struct mds_rec_link { - __u32 lk_opcode; - __u32 lk_fsuid; - __u32 lk_fsgid; - __u32 lk_cap; - __u32 lk_suppgid; - 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; - __u32 ul_suppgid; - 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; - __u32 rn_suppgid1; - __u32 rn_suppgid2; - 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 */ - struct obd_uuid 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 - -struct ldlm_res_id { - __u64 name[RES_NAME_SIZE]; -}; - -/* 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; - struct ldlm_res_id lr_name; - __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; - struct ldlm_res_id lock_resource_name; - struct lustre_handle lock_handle; - struct ldlm_extent lock_extent; /* XXX make this policy 1 &2 */ - __u64 lock_policy_res1; - __u64 lock_policy_res2; -}; - -/* - * ptlbd, portal block device requests - */ -typedef enum { - PTLBD_QUERY = 200, - PTLBD_READ = 201, - PTLBD_WRITE = 202, -} ptlbd_cmd_t; - -struct ptlbd_op { - __u16 op_cmd; - __u16 op_lun; - __u16 op_niob_cnt; - __u16 op__padding; - __u32 op_block_cnt; -}; - -struct ptlbd_niob { - __u64 n_xid; - __u64 n_block_nr; - __u32 n_offset; - __u32 n_length; -}; - -struct ptlbd_rsp { - __u16 r_status; - __u16 r_error_cnt; -}; -#endif diff --git a/lustre/include/linux/lustre_import.h b/lustre/include/linux/lustre_import.h deleted file mode 100644 index 4fc2581..0000000 --- a/lustre/include/linux/lustre_import.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) 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 - - -#define IMP_INVALID 1 -#define IMP_REPLAYABLE 2 - - -struct obd_import; -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_max_transno; - __u64 imp_peer_committed_transno; - - /* Protects flags, level, *_list */ - spinlock_t imp_lock; -}; - -extern struct obd_import *class_conn2cliimp(struct lustre_handle *); -extern struct obd_import *class_conn2ldlmimp(struct lustre_handle *); - - -#endif /* __IMPORT_H */ diff --git a/lustre/include/linux/lustre_lib.h b/lustre/include/linux/lustre_lib.h deleted file mode 100644 index 41c67fff..0000000 --- a/lustre/include/linux/lustre_lib.h +++ /dev/null @@ -1,649 +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 -#include -#include /* XXX just for LASSERT! */ -#include - -#ifndef LPU64 -#if BITS_PER_LONG > 32 -#define LPU64 "%lu" -#define LPD64 "%ld" -#define LPX64 "%#lx" -#else -#define LPU64 "%Lu" -#define LPD64 "%Ld" -#define LPX64 "%#Lx" -#endif -#endif - -/* target.c */ -struct ptlrpc_request; -struct obd_device; -struct recovd_data; -struct recovd_obd; -struct obd_export; -#include -#include - - -int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler); -int target_handle_disconnect(struct ptlrpc_request *req); -int target_handle_reconnect(struct lustre_handle *conn, struct obd_export *exp, - struct obd_uuid *cluuid); -int target_revoke_connection(struct recovd_data *rd, int phase); - -#define OBD_RECOVERY_TIMEOUT (obd_timeout * 5 * HZ / 2) /* *waves hands* */ -void target_start_recovery_timer(struct obd_device *obd, svc_handler_t handler); -void target_abort_recovery(void *data); -int target_queue_recovery_request(struct ptlrpc_request *req, - struct obd_device *obd); -int target_queue_final_reply(struct ptlrpc_request *req, int rc); - -/* client.c */ -int client_obd_connect(struct lustre_handle *conn, struct obd_device *obd, - struct obd_uuid *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_sanobd_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); -struct obd_device *client_tgtuuid2obd(struct obd_uuid *tgtuuid); - -/* statfs_pack.c */ -int obd_self_statfs(struct obd_device *dev, struct statfs *sfs); - -/* 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); - -#ifdef __KERNEL__ - -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; -} - -#include - -/* - * OBD IOCTLS - */ -#define OBD_IOCTL_VERSION 0x00010002 - -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 ioc_command; - - uint64_t ioc_nid; - uint32_t ioc_nal; - - /* 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 (%d != %d)\n", - obd_ioctl_packlen(data), data->ioc_len); - 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; -} -#endif - -#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; -} - -#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_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_IOC_NO_TRANSNO _IOW ('f', 140, long) -#define OBD_IOC_SET_READONLY _IOW ('f', 141, long) - -#define OBD_GET_VERSION _IOWR ('f', 144, long) - -#define OBD_IOC_ADD_UUID _IOWR ('f', 145, long) -#define OBD_IOC_DEL_UUID _IOWR ('f', 146, long) -#define OBD_IOC_CLOSE_UUID _IOWR ('f', 147, long) - -#define ECHO_IOC_GET_STRIPE _IOWR('f', 200, long) -#define ECHO_IOC_SET_STRIPE _IOWR('f', 201, long) -#define ECHO_IOC_ENQUEUE _IOWR('f', 202, long) -#define ECHO_IOC_CANCEL _IOWR('f', 203, long) - - -#define CHECKSUM_BULK 0 - -#if CHECKSUM_BULK -static inline void ost_checksum(__u64 *cksum, void *addr, int len) -{ - unsigned char *ptr = (unsigned char *)addr; - __u64 sum = 0; - - /* very stupid, but means I don't have to think about byte order */ - while (len-- > 0) - sum += *ptr++; - - *cksum = (*cksum << 2) + sum; -} -#else -#define ost_checksum(cksum, addr, len) do {} while (0) -#endif - -/* - * 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 \ -}) - -#ifdef __KERNEL__ -#define l_sigismember sigismember -#else -#define l_sigismember(a,b) (*(a) & b) -#endif - -/* XXX this should be one mask-check */ -#define l_killable_pending(task) \ -(l_sigismember(&(task->pending.signal), SIGKILL) || \ - l_sigismember(&(task->pending.signal), SIGINT) || \ - l_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 0c29c79..0000000 --- a/lustre/include/linux/lustre_lite.h +++ /dev/null @@ -1,288 +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 ptlrpc_request *fd_req; - char fd_ostdata[FD_OSTDATA_SIZE]; - __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; -}; - -struct ll_inode_info { - struct lov_stripe_md *lli_smd; - char *lli_symlink_name; - struct semaphore lli_open_sem; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) - struct inode lli_vfs_inode; -#endif -}; - -/* interpet return codes from intent lookup */ -#define LL_LOOKUP_POSITIVE 1 -#define LL_LOOKUP_NEGATIVE 2 - -#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 { - struct obd_uuid 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); -} - -static inline void d_unhash_aliases(struct inode *inode) -{ - struct dentry *dentry = NULL; - struct list_head *tmp; - struct ll_sb_info *sbi = ll_i2sbi(inode); - ENTRY; - - CDEBUG(D_INODE, "marking dentries for ino %lx/%x invalid\n", - inode->i_ino, inode->i_generation); - - 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); - dentry->d_flags |= DCACHE_LUSTRE_INVALID; - list_add(&dentry->d_hash, &sbi->ll_orphan_dentry_list); - } - - spin_unlock(&dcache_lock); - EXIT; -} - -// 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 *); - -/**** - -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) - -/* dcache.c */ -int ll_have_md_lock(struct dentry *de); - -/* 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; -extern struct inode_operations ll_special_inode_operations; -struct ldlm_lock; -int ll_lock_callback(struct ldlm_lock *, struct ldlm_lock_desc *, void *data, - 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, char *ostdata); -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 *, struct lov_mds_md *); -int ll_setattr_raw(struct inode *inode, struct iattr *attr); - -/* 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 0a881b1..0000000 --- a/lustre/include/linux/lustre_mds.h +++ /dev/null @@ -1,302 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2001-2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * MDS data structures. - * See also lustre_idl.h for wire formats of requests. - * - */ - -#ifndef _LUSTRE_MDS_H -#define _LUSTRE_MDS_H - -#ifdef __KERNEL__ -#include -#endif -#include -#include - -struct ldlm_lock_desc; -struct mds_obd; -struct ptlrpc_connection; -struct ptlrpc_client; -struct obd_export; -struct ptlrpc_request; -struct obd_device; -struct ll_file_data; - -#define LUSTRE_MDS_NAME "mds" -#define LUSTRE_MDT_NAME "mdt" -#define LUSTRE_MDC_NAME "mdc" - -struct mdc_rpc_lock { - struct semaphore rpcl_sem; - struct lookup_intent *rpcl_it; -}; -extern struct mdc_rpc_lock mdc_rpc_lock; -extern struct mdc_rpc_lock mdc_setattr_lock; - -static inline void mdc_init_rpc_lock(struct mdc_rpc_lock *lck) -{ - sema_init(&lck->rpcl_sem, 1); - lck->rpcl_it = NULL; -} - -static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck, - struct lookup_intent *it) -{ - down(&lck->rpcl_sem); - if (it) { - lck->rpcl_it = it; - it->it_iattr = (void *)1; - } -} - -static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck, - struct lookup_intent *it) -{ - if (it == NULL) { - LASSERT(it == lck->rpcl_it); - up(&lck->rpcl_sem); - return; - } - if (it && it->it_iattr) { - it->it_iattr = NULL; - LASSERT(it == lck->rpcl_it); - lck->rpcl_it = NULL; - up(&lck->rpcl_sem); - } -} -struct mdc_unlink_data { - struct inode *unl_dir; - struct inode *unl_de; - int unl_mode; - const char *unl_name; - int unl_len; -}; - -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; - __u32 ur_flags; - __u32 ur_suppgid1; - __u32 ur_suppgid2; -}; - -#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_transno; /* 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_mount_count; /* MDS incarnation number */ - __u64 mcd_last_transno; /* last completed transaction ID */ - __u64 mcd_last_xid; /* xid for the last transaction */ - __u32 mcd_last_result; /* result from last RPC */ - __u32 mcd_last_data; /* per-op data (disposition for open &c.) */ - __u8 padding[MDS_LR_SIZE - 58]; -}; - -/* 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; - struct ptlrpc_request *med_outstanding_reply; -}; - -/* file data for open files on MDS */ -struct mds_file_data { - struct list_head mfd_list; - __u64 mfd_servercookie; - __u64 mfd_xid; - struct file *mfd_file; -}; - -/* mds/mds_reint.c */ -int mds_reint_rec(struct mds_update_record *r, int offset, - struct ptlrpc_request *req, struct lustre_handle *); - -/* mds/mds_open.c */ -int mds_open(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req, struct lustre_handle *); - -/* 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, __u64 xid); -void mds_getattr_pack(struct ptlrpc_request *req, int valid, int offset, int fl, - struct inode *inode, const char *name, int namelen); -void mds_setattr_pack(struct ptlrpc_request *, struct inode *, - struct iattr *, void *ea, int ealen); -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_open_pack(struct ptlrpc_request *, int offset, struct inode *dir, - __u32 mode, __u64 rdev, __u32 uid, __u32 gid, __u64 time, - __u32 flags, 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, struct lustre_handle *); -int mds_pack_md(struct obd_device *mds, struct lustre_msg *msg, - int offset, struct mds_body *body, struct inode *inode); -void mds_steal_ack_locks(struct mds_export_data *med, - struct ptlrpc_request *req); - -/* mds/mds_fs.c */ -int mds_fs_setup(struct obd_device *obddev, struct vfsmount *mnt); -int mds_fs_cleanup(struct obd_device *obddev); - -/* 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, unsigned int ea_size, - struct ptlrpc_request **request); -int mdc_getattr_name(struct lustre_handle *conn, struct inode *parent, - char *filename, int namelen, unsigned long valid, - unsigned int ea_size, struct ptlrpc_request **request); -int mdc_setattr(struct lustre_handle *conn, - struct inode *, struct iattr *iattr, - void *ea, int ealen, 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 **); -void mdc_set_open_replay_data(struct ll_file_data *fd); -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 inode *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(struct obd_uuid uuid, struct ptlrpc_client *cl); -void mdc_lock_set_inode(struct lustre_handle *lock, struct inode *inode); - -/* 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); - - -/* 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 - -#define MDS_CHECK_RESENT(req, reconstruct) \ -{ \ - if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) { \ - struct mds_client_data *mcd = \ - req->rq_export->exp_mds_data.med_mcd; \ - if (mcd->mcd_last_xid == req->rq_xid) { \ - reconstruct; \ - RETURN(0); \ - } \ - DEBUG_REQ(D_HA, req, "no reply for RESENT req (have "LPD64")", \ - mcd->mcd_last_xid); \ - } \ -} - -#endif diff --git a/lustre/include/linux/lustre_net.h b/lustre/include/linux/lustre_net.h deleted file mode 100644 index 8c50212..0000000 --- a/lustre/include/linux/lustre_net.h +++ /dev/null @@ -1,450 +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 - -#ifdef __KERNEL__ -#include -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#include -#else -#include -#endif -#endif - -#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_NEVENT_MAX 8192UL -#define LDLM_NEVENTS min(num_physpages / 64, LDLM_NEVENT_MAX) -#define LDLM_NBUF_MAX 256UL -#define LDLM_NBUFS min(LDLM_NEVENTS / 16, LDLM_NBUF_MAX) -#define LDLM_BUFSIZE (8 * 1024) -#define LDLM_MAXREQSIZE 1024 - -#define MDT_NUM_THREADS 8 -#define MDS_NEVENT_MAX 8192UL -#define MDS_NEVENTS min(num_physpages / 64, MDS_NEVENT_MAX) -#define MDS_NBUF_MAX 512UL -#define MDS_NBUFS min(MDS_NEVENTS / 16, MDS_NBUF_MAX) -#define MDS_BUFSIZE (8 * 1024) -/* Assume file name length = FNAME_MAX = 256 (true for extN). - * path name length = PATH_MAX = 4096 - * LOV MD size max = EA_MAX = 4000 - * symlink: FNAME_MAX + PATH_MAX <- largest - * link: FNAME_MAX + PATH_MAX (mds_rec_link < mds_rec_create) - * rename: FNAME_MAX + FNAME_MAX - * open: FNAME_MAX + EA_MAX - * - * MDS_MAXREQSIZE ~= 4736 bytes = - * lustre_msg + ldlm_request + mds_body + mds_rec_create + FNAME_MAX + PATH_MAX - * - * Realistic size is about 512 bytes (20 character name + 128 char symlink), - * except in the open case where there are a large number of OSTs in a LOV. - */ -#define MDS_MAXREQSIZE (5 * 1024) - -#define OST_NUM_THREADS 6 -#define OST_NEVENT_MAX 32768UL -#define OST_NEVENTS min(num_physpages / 16, OST_NEVENT_MAX) -#define OST_NBUF_MAX 1280UL -#define OST_NBUFS min(OST_NEVENTS / 64, OST_NBUF_MAX) -#define OST_BUFSIZE (8 * 1024) -/* OST_MAXREQSIZE ~= 1896 bytes = - * lustre_msg + obdo + 16 * obd_ioobj + 64 * niobuf_remote - * - * single object with 16 pages is 576 bytes - */ -#define OST_MAXREQSIZE (2 * 1024) - -#define PTLBD_NUM_THREADS 4 -#define PTLBD_NEVENTS 1024 -#define PTLBD_NBUFS 20 -#define PTLBD_BUFSIZE (32 * 1024) -#define PTLBD_MAXREQSIZE 1024 - -#define CONN_INVALID 1 - -struct ptlrpc_peer { - ptl_nid_t peer_nid; - struct ptlrpc_ni *peer_ni; -}; - -struct ptlrpc_connection { - struct list_head c_link; - struct ptlrpc_peer c_peer; - struct obd_uuid c_local_uuid; /* XXX do we need this? */ - struct obd_uuid c_remote_uuid; - - __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) /* reply wait was interrupted by user */ -#define PTL_RPC_FL_REPLIED (1 << 1) /* reply was received */ -#define PTL_RPC_FL_SENT (1 << 2) /* request was sent */ -#define PTL_RPC_FL_WANT_ACK (1 << 3) /* reply is awaiting an ACK */ -#define PTL_BULK_FL_SENT (1 << 4) /* outgoing bulk was sent */ -#define PTL_BULK_FL_RCVD (1 << 5) /* incoming bulk was recieved */ -#define PTL_RPC_FL_ERR (1 << 6) /* request failed due to RPC error */ -#define PTL_RPC_FL_TIMEOUT (1 << 7) /* request timed out waiting for reply */ -#define PTL_RPC_FL_RESEND (1 << 8) /* retransmit the request */ -#define PTL_RPC_FL_RESTART (1 << 9) /* operation must be restarted */ -#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 */ -#define PTL_RPC_FL_NO_RESEND (1 << 13) /* don't automatically resend this req */ -#define PTL_RPC_FL_RESENT (1 << 14) /* server rcvd resend of this req */ - -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; - wait_queue_head_t rq_wait_for_rep; /* XXX also _for_ack */ - - /* 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 ptlrpc_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 *); - void *rq_replay_data; - - /* Only used on the server side for tracking acks. */ - struct ptlrpc_req_ack_lock { - struct lustre_handle lock; - __u32 mode; - } rq_ack_locks[4]; -}; - -#define DEBUG_REQ(level, req, fmt, args...) \ -do { \ -CDEBUG(level, \ - "@@@ " fmt " req@%p x"LPD64"/t"LPD64" o%d->%s:%d lens %d/%d ref %d fl " \ - "%x/%x/%x rc %x\n" , ## args, req, req->rq_xid, \ - req->rq_reqmsg ? req->rq_reqmsg->transno : -1, \ - req->rq_reqmsg ? req->rq_reqmsg->opc : -1, \ - req->rq_connection ? \ - (char *)req->rq_connection->c_remote_uuid.uuid : "", \ - (req->rq_import && req->rq_import->imp_client) ? \ - req->rq_import->imp_client->cli_request_portal : -1, \ - req->rq_reqlen, req->rq_replen, \ - atomic_read (&req->rq_refcount), req->rq_flags, \ - req->rq_reqmsg ? req->rq_reqmsg->flags : 0, \ - req->rq_repmsg ? req->rq_repmsg->flags : 0, \ - req->rq_status); \ -} 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_srv_ni *rqbd_srv_ni; - ptl_handle_me_t rqbd_me_h; - atomic_t rqbd_refcount; - char *rqbd_buffer; -}; - -struct ptlrpc_ni { - /* Generic interface state */ - char *pni_name; - ptl_handle_ni_t pni_ni_h; - ptl_handle_eq_t pni_request_out_eq_h; - ptl_handle_eq_t pni_reply_in_eq_h; - ptl_handle_eq_t pni_reply_out_eq_h; - ptl_handle_eq_t pni_bulk_put_source_eq_h; - ptl_handle_eq_t pni_bulk_put_sink_eq_h; - ptl_handle_eq_t pni_bulk_get_source_eq_h; - ptl_handle_eq_t pni_bulk_get_sink_eq_h; -}; - -struct ptlrpc_srv_ni { - /* Interface-specific service state */ - struct ptlrpc_service *sni_service; /* owning service */ - struct ptlrpc_ni *sni_ni; /* network interface */ - ptl_handle_eq_t sni_eq_h; /* event queue handle */ - struct list_head sni_rqbds; /* all the request buffer descriptors */ - __u32 sni_nrqbds; /* # request buffers */ - atomic_t sni_nrqbds_receiving; /* # request buffers posted */ -}; - -struct ptlrpc_service { - time_t srv_time; - time_t srv_timeout; - - struct list_head srv_ni_list; /* list of interfaces */ - __u32 srv_max_req_size; /* biggest request to receive */ - __u32 srv_buf_size; /* # bytes in a request buffer */ - - __u32 srv_req_portal; - __u32 srv_rep_portal; - - __u32 srv_xid; - - 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 */ - - int srv_interface_rover; - struct ptlrpc_srv_ni srv_interfaces[0]; -}; - -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/events.c */ -extern struct ptlrpc_ni ptlrpc_interfaces[]; -extern int ptlrpc_ninterfaces; -extern int ptlrpc_uuid_to_peer (struct obd_uuid *uuid, struct ptlrpc_peer *peer); - -/* rpc/connection.c */ -void ptlrpc_readdress_connection(struct ptlrpc_connection *, struct obd_uuid *uuid); -struct ptlrpc_connection *ptlrpc_get_connection(struct ptlrpc_peer *peer, - struct obd_uuid *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_bulk_put(struct ptlrpc_bulk_desc *); -int ptlrpc_bulk_get(struct ptlrpc_bulk_desc *); -int ptlrpc_register_bulk_put(struct ptlrpc_bulk_desc *); -int ptlrpc_register_bulk_get(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_del(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); -struct obd_uuid *ptlrpc_req_to_uuid(struct ptlrpc_request *req); -struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *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); -int ptlrpc_abort(struct ptlrpc_request *req); -void ptlrpc_restart_req(struct ptlrpc_request *req); -void ptlrpc_abort_inflight(struct obd_import *imp, int dying_import); - -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_request *ptlrpc_request_addref(struct ptlrpc_request *req); -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); -void ptlrpc_retain_replayable_request(struct ptlrpc_request *req, - struct obd_import *imp); - -/* 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, 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); - -/* rpc/rpc.c */ -__u32 ptlrpc_next_xid(void); - -static inline void ptlrpc_bulk_decref(struct ptlrpc_bulk_desc *desc) -{ - CDEBUG(D_PAGE, "%p -> %d\n", desc, atomic_read(&desc->bd_refcount) - 1); - - if (atomic_dec_and_test(&desc->bd_refcount)) { - CDEBUG(D_PAGE, "Released last ref on %p, freeing\n", desc); - ptlrpc_free_bulk(desc); - } -} - -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 f3163fe..0000000 --- a/lustre/include/linux/obd.h +++ /dev/null @@ -1,417 +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; /* open file handle for obj on OST */ - int loi_ost_idx; /* OST stripe index in lmd_objects array */ -}; - -struct lov_stripe_md { - __u64 lsm_object_id; /* lov object id */ - __u32 lsm_magic; - __u32 lsm_stripe_size; /* size of the stripe */ - unsigned lsm_stripe_offset; /* offset of first stripe in lmd_objects */ - unsigned lsm_stripe_count; /* how many objects are being striped on */ - struct lov_oinfo lsm_oinfo[0]; -}; - -#define IOC_OSC_TYPE 'h' -#define IOC_OSC_MIN_NR 20 -#define IOC_OSC_REGISTER_LOV _IOWR(IOC_OSC_TYPE, 20, struct obd_device *) -#define IOC_OSC_MAX_NR 50 - -#define IOC_MDC_TYPE 'i' -#define IOC_MDC_MIN_NR 20 -#define IOC_MDC_LOOKUP _IOWR(IOC_MDC_TYPE, 20, struct obd_device *) -#define IOC_MDC_MAX_NR 50 - -#ifdef __KERNEL__ -# include -# include -# include /* for struct task_struct, for current.h */ -# include /* for smp_lock.h */ -# include -# include - -# include -# include -# include -# include -#endif - -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 { - obd_off off; - struct page *pg; - int count; - 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; - __u32 ouc_suppgid1; - __u32 ouc_suppgid2; -}; - -#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 ost_server_data; - -#define FILTER_TRANSNO_SEM - -#ifndef OST_RECOVERY -#undef FILTER_TRANSNO_SEM -#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]; - struct dentry **fo_dentry_O_sub; - spinlock_t fo_objidlock; /* protects fo_lastobjid increment */ -#ifdef FILTER_TRANSNO_SEM - struct semaphore fo_transno_sem; -#else - spinlock_t fo_translock; /* protects fsd_last_rcvd increment */ -#endif - struct file *fo_rcvd_filp; - struct filter_server_data *fo_fsd; - unsigned long *fo_last_rcvd_slots; - - 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 */ - int fo_subdir_count; -}; - -struct mds_server_data; - -struct client_obd { - struct obd_import cl_import; - struct semaphore cl_sem; - int cl_conn_count; - struct obd_uuid 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; - kdev_t cl_sandev; -}; - -struct mds_obd { - struct ptlrpc_service *mds_service; - struct ptlrpc_service *mds_setattr_service; - struct ptlrpc_service *mds_readpage_service; - - struct super_block *mds_sb; - 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; - - int mds_max_mdsize; - struct file *mds_rcvd_filp; - spinlock_t mds_transno_lock; - __u64 mds_last_transno; - __u64 mds_mount_count; - struct ll_fid mds_rootfid; - struct mds_server_data *mds_server_data; - - int mds_has_lov_desc; - struct lov_desc mds_lov_desc; -}; - -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; -}; - -/* - * this struct does double-duty acting as either a client or - * server instance .. maybe not wise. - */ -struct ptlbd_obd { - /* server's */ - struct ptlrpc_service *ptlbd_service; - struct file *filp; - /* client's */ - struct ptlrpc_client bd_client; - struct obd_import bd_import; - int refcount; /* XXX sigh */ -}; - -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 echo_client_obd { - struct lustre_handle ec_conn; /* the local connection to osc/lov */ - spinlock_t ec_lock; - struct list_head ec_objects; - int ec_lsmsize; - int ec_nstripes; - __u64 ec_unique; -}; - -struct cache_obd { - struct lustre_handle cobd_target; /* local connection to target obd */ - struct lustre_handle cobd_cache; /* local connection to cache obd */ -}; - -struct lov_tgt_desc { - struct obd_uuid 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; -}; - -/* Don't conflict with on-wire flags OBD_BRW_WRITE, etc */ -#define N_LOCAL_TEMP_PAGE 0x10000000 - -struct obd_trans_info { - __u64 oti_transno; -}; - -/* 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; - struct obd_uuid 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; - __u64 obd_last_committed; - struct fsfilt_operations *obd_fsops; - - /* XXX encapsulate all this recovery data into one struct */ - svc_handler_t obd_recovery_handler; - int obd_recoverable_clients; - spinlock_t obd_processing_task_lock; - pid_t obd_processing_task; - __u64 obd_next_recovery_transno; - wait_queue_head_t obd_next_transno_waitq; - struct timer_list obd_recovery_timer; - struct list_head obd_recovery_queue; - struct list_head obd_delayed_reply_queue; - - 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 ldlm_obd ldlm; - struct echo_obd echo; - struct recovd_obd recovd; - struct trace_obd trace; - struct lov_obd lov; - struct cache_obd cobd; - struct ptlbd_obd ptlbd; -#if 0 - struct snap_obd snap; -#endif - } u; - /* Fields used by LProcFS */ - unsigned int cntr_mem_size; - void *counters; -}; - -struct obd_ops { - struct module *o_owner; - 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, - struct obd_uuid *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_syncfs)(struct lustre_handle *conn); - 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, struct obd_trans_info *oti); - int (*o_destroy)(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea, struct obd_trans_info *oti); - int (*o_setattr)(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea, struct obd_trans_info *oti); - 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, struct obd_trans_info *oti); - int (*o_close)(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea, struct obd_trans_info *oti); - 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 *, - struct obd_trans_info *oti); - int (*o_punch)(struct lustre_handle *conn, struct obdo *tgt, - struct lov_stripe_md *ea, obd_size count, - obd_off offset, struct obd_trans_info *oti); - 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, struct obd_trans_info *); - 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, - struct obd_trans_info *oti); - int (*o_commitrw)(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_local *local, - void *desc_private, struct obd_trans_info *oti); - 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); - int (*o_san_preprw)(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_remote *remote); -}; -#endif /* __OBD_H */ diff --git a/lustre/include/linux/obd_cache.h b/lustre/include/linux/obd_cache.h deleted file mode 100644 index e75b9f4..0000000 --- a/lustre/include/linux/obd_cache.h +++ /dev/null @@ -1,13 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - */ - -#ifndef _OBD_CACHE_H__ -#define _OBD_CACHE_H__ - -#ifdef __KERNEL__ - -#define OBD_CACHE_DEVICENAME "cobd" - -#endif -#endif diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h deleted file mode 100644 index f626bab..0000000 --- a/lustre/include/linux/obd_class.h +++ /dev/null @@ -1,978 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2001-2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef __LINUX_CLASS_OBD_H -#define __LINUX_CLASS_OBD_H - -#ifndef __KERNEL__ -# include -# define __KERNEL__ -# include -# undef __KERNEL__ -#else -#include -#include -#include -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* OBD Device Declarations */ -#define MAX_OBD_DEVICES 128 -extern struct obd_device obd_dev[MAX_OBD_DEVICES]; - -#define OBD_ATTACHED 0x01 -#define OBD_SET_UP 0x02 -#define OBD_RECOVERING 0x04 -#define OBD_ABORT_RECOVERY 0x08 -#define OBD_REPLAYABLE 0x10 -#define OBD_NO_TRANSNO 0x20 /* XXX needs better name */ - -/* OBD Operations Declarations */ -extern struct obd_device *class_conn2obd(struct lustre_handle *); -extern struct obd_export *class_conn2export(struct lustre_handle *); - -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 for conn "LPX64":"LPX64"\n", \ - conn->addr, conn->cookie); \ - 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_trans_info *oti) -{ - 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, oti); - RETURN(rc); -} - -static inline int obd_destroy(struct lustre_handle *conn, struct obdo *obdo, - struct lov_stripe_md *ea, - struct obd_trans_info *oti) -{ - 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, oti); - 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_trans_info *oti) -{ - 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, oti); - RETURN(rc); -} - -static inline int obd_open(struct lustre_handle *conn, struct obdo *obdo, - struct lov_stripe_md *ea, struct obd_trans_info *oti) -{ - 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, oti); - RETURN(rc); -} - -static inline int obd_setattr(struct lustre_handle *conn, struct obdo *obdo, - struct lov_stripe_md *ea, - struct obd_trans_info *oti) -{ - 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, oti); - RETURN(rc); -} - -static inline int obd_connect(struct lustre_handle *conn, - struct obd_device *obd, struct obd_uuid *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_syncfs(struct lustre_handle *conn) -{ - struct obd_export *exp; - int rc; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, syncfs); - - rc = OBP(exp->exp_obd, syncfs)(conn); - 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_trans_info *oti) -{ - 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, oti); - 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_trans_info *oti) -{ - 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, oti); - 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_trans_info *oti) -{ - 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, oti); - 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_trans_info *oti) -{ - 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, oti); - 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); -} - -static inline int obd_san_preprw(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_remote *remote) -{ - struct obd_export *exp; - int rc; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, preprw); - - rc = OBP(exp->exp_obd, san_preprw)(cmd, conn, objcount, obj, - niocount, remote); - RETURN(rc); -} - - -/* 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; -} - -/* 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); -} - -#ifdef __KERNEL__ -static inline void obdo_from_iattr(struct obdo *oa, struct iattr *attr) -{ - unsigned int ia_valid = attr->ia_valid; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - 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; - } -#else - if (ia_valid & ATTR_ATIME) { - oa->o_atime = attr->ia_atime.tv_sec; - oa->o_valid |= OBD_MD_FLATIME; - } - if (ia_valid & ATTR_MTIME) { - oa->o_mtime = attr->ia_mtime.tv_sec; - oa->o_valid |= OBD_MD_FLMTIME; - } - if (ia_valid & ATTR_CTIME) { - oa->o_ctime = attr->ia_ctime.tv_sec; - oa->o_valid |= OBD_MD_FLCTIME; - } -#endif - - 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 (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - 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; - } -#else - if (valid & OBD_MD_FLATIME) { - attr->ia_atime.tv_sec = oa->o_atime; - attr->ia_valid |= ATTR_ATIME; - } - if (valid & OBD_MD_FLMTIME) { - attr->ia_mtime.tv_sec = oa->o_mtime; - attr->ia_valid |= ATTR_MTIME; - } - if (valid & OBD_MD_FLCTIME) { - attr->ia_ctime.tv_sec = oa->o_ctime; - attr->ia_valid |= ATTR_CTIME; - } -#endif - 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 (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - 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; -#else - if (valid & OBD_MD_FLATIME) - dst->o_atime = src->i_atime.tv_sec; - if (valid & OBD_MD_FLMTIME) - dst->o_mtime = src->i_mtime.tv_sec; - if (valid & OBD_MD_FLCTIME) - dst->o_ctime = src->i_ctime.tv_sec; -#endif - 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) -{ - valid &= src->o_valid; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - 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 && src->o_ctime > dst->i_ctime) - dst->i_ctime = src->o_ctime; -#else - if (valid & OBD_MD_FLATIME) - dst->i_atime.tv_sec = src->o_atime; - if (valid & OBD_MD_FLMTIME) - dst->i_mtime.tv_sec = src->o_mtime; - if (valid & OBD_MD_FLCTIME && src->o_ctime > dst->i_ctime.tv_sec) - dst->i_ctime.tv_sec = src->o_ctime; -#endif - 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; -} - - -/* 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); -extern void (*ptlrpc_abort_inflight_superhack)(struct obd_import *imp, - int dying_import); - -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(struct obd_uuid *uuid); -struct obd_device *class_uuid2obd(struct obd_uuid *uuid); -struct obd_export *class_new_export(struct obd_device *obddev); -struct obd_type *class_get_type(char *name); -void class_put_type(struct obd_type *type); -void class_destroy_export(struct obd_export *exp); -int class_connect(struct lustre_handle *conn, struct obd_device *obd, - struct obd_uuid *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); -} - -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); -void obd_statfs_unpack(struct obd_statfs *tgt, struct obd_statfs *src); - - -struct obd_class_user_state { - struct obd_device *ocus_current_obd; - struct list_head ocus_conns; -}; - -struct obd_class_user_conn { - struct list_head ocuc_chain; - struct lustre_handle ocuc_conn; -}; - - -/* 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(struct obd_uuid in, class_uuid_t out); -void class_uuid_unparse(class_uuid_t in, struct obd_uuid *out); - -/* lustre_peer.c */ -int lustre_uuid_to_peer(char *uuid, struct lustre_peer *peer); -int class_add_uuid(char *uuid, __u64 nid, __u32 nal); -int class_del_uuid (char *uuid); -void class_init_uuidlist(void); -void class_exit_uuidlist(void); - -#endif /* __LINUX_OBD_CLASS_H */ diff --git a/lustre/include/linux/obd_echo.h b/lustre/include/linux/obd_echo.h deleted file mode 100644 index 273779a..0000000 --- a/lustre/include/linux/obd_echo.h +++ /dev/null @@ -1,41 +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" - -struct ec_object -{ - struct list_head eco_obj_chain; - struct obd_device *eco_device; - int eco_refcount; - int eco_deleted; - obd_id eco_id; - struct lov_stripe_md *eco_lsm; -}; - -struct ec_open_object -{ - struct list_head ecoo_exp_chain; - struct ec_object *ecoo_object; - struct obdo ecoo_oa; - __u64 ecoo_cookie; -}; - -struct ec_lock -{ - struct list_head ecl_exp_chain; - struct lustre_handle ecl_handle; - struct ldlm_extent ecl_extent; - __u32 ecl_mode; - struct ec_object *ecl_object; - __u64 ecl_cookie; -}; - -#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 26850d8..0000000 --- a/lustre/include/linux/obd_filter.h +++ /dev/null @@ -1,96 +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 - -#define FILTER_LR_SERVER_SIZE 512 - -#define FILTER_LR_CLIENT_START 8192 -#define FILTER_LR_CLIENT_SIZE 128 - -#define FILTER_SUBDIR_COUNT 32 /* set to zero for no subdirs */ - -#define FILTER_MOUNT_RECOV 2 -#define FILTER_RECOVERY_TIMEOUT (obd_timeout * 5 * HZ / 2) /* *waves hands* */ - -/* Data stored per server at the head of the last_rcvd file. In le32 order. */ -struct filter_server_data { - __u8 fsd_uuid[37]; /* server UUID */ - __u8 fsd_uuid_padding[3]; /* unused */ - __u64 fsd_last_objid; /* last created object ID */ - __u64 fsd_last_rcvd; /* last completed transaction ID */ - __u64 fsd_mount_count; /* FILTER incarnation number */ - __u32 fsd_feature_compat; /* compatible feature flags */ - __u32 fsd_feature_rocompat;/* read-only compatible feature flags */ - __u32 fsd_feature_incompat;/* incompatible feature flags */ - __u32 fsd_server_size; /* size of server data area */ - __u32 fsd_client_start; /* start of per-client data area */ - __u16 fsd_client_size; /* size of per-client data area */ - __u16 fsd_subdir_count; /* number of subdirectories for objects */ - __u8 fsd_padding[FILTER_LR_SERVER_SIZE - 88]; -}; - -/* Data stored per client in the last_rcvd file. In le32 order. */ -struct filter_client_data { - __u8 fcd_uuid[37]; /* client UUID */ - __u8 fcd_uuid_padding[3]; /* unused */ - __u64 fcd_last_rcvd; /* last completed transaction ID */ - __u64 fcd_mount_count; /* FILTER incarnation number */ - __u64 fcd_last_xid; /* client RPC xid for the last transaction */ - __u8 fcd_padding[FILTER_LR_CLIENT_SIZE - 64]; -}; - -#ifndef OBD_FILTER_SAN_DEVICENAME -#define OBD_FILTER_SAN_DEVICENAME "sanobdfilter" -#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 */ - struct filter_client_data *fed_fcd; - loff_t fed_lr_off; - int fed_lr_idx; -}; - -/* 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 { - obd_id fdd_objid; - 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 ff3e689..0000000 --- a/lustre/include/linux/obd_lov.h +++ /dev/null @@ -1,28 +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__ - -#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); -} - -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 f8d1486..0000000 --- a/lustre/include/linux/obd_ost.h +++ /dev/null @@ -1,44 +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" -#define LUSTRE_SANOSC_NAME "sanosc" -#define LUSTRE_SANOST_NAME "sanost" - -/* 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(struct obd_ioobj **ioop, struct lov_stripe_md *oa,int bufcnt); -void ost_unpack_ioo(struct obd_ioobj **tmp, struct obd_ioobj **ioop); - -#endif diff --git a/lustre/include/linux/obd_ptlbd.h b/lustre/include/linux/obd_ptlbd.h deleted file mode 100644 index b4f9fe9..0000000 --- a/lustre/include/linux/obd_ptlbd.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _OBD_PTLBD_H -#define _OBD_PTLBD_H - -#include -/* - * Copyright (C) 2002 Cluster File Systems, Inc. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ - -#define OBD_PTLBD_SV_DEVICENAME "ptlbd_server" -#define OBD_PTLBD_CL_DEVICENAME "ptlbd_client" - -/* XXX maybe this isn't the best header to be dumping all this in.. */ - -extern int ptlbd_blk_init(void); -extern int ptlbd_cl_init(void); -extern int ptlbd_sv_init(void); - -extern void ptlbd_blk_exit(void); -extern void ptlbd_cl_exit(void); -extern void ptlbd_sv_exit(void); - -extern void ptlbd_blk_register(struct ptlbd_obd *ptlbd); -extern int ptlbd_send_req(struct ptlbd_obd *, ptlbd_cmd_t cmd, - struct buffer_head *); -extern int ptlbd_parse_req(struct ptlrpc_request *req); - -#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 a4d676d..0000000 --- a/lustre/include/linux/obd_support.h +++ /dev/null @@ -1,229 +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 - -#ifdef __KERNEL__ -#include -#include -#include -#include -#else - -#endif -#include - -/* global variables */ -extern atomic_t obd_memory; -extern int obd_memmax; -extern unsigned long obd_fail_loc; -extern unsigned long obd_timeout; -extern char obd_recovery_upcall[128]; -extern unsigned long obd_sync_filter; - -#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_MDS_GETATTR_NAME_NET 0x11f -#define OBD_FAIL_MDS_ALL_REPLY_NET 0x120 -#define OBD_FAIL_MDS_ALL_REQUEST_NET 0x121 - -#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_OST_SYNCFS_NET 0x210 - -#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 - -#define OBD_FAIL_PTLRPC 0x500 -#define OBD_FAIL_PTLRPC_ACK 0x501 - -/* 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_MASK_LOC)) && \ - ((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) - -#define fixme() CDEBUG(D_OTHER, "FIXME\n"); - -#ifdef __KERNEL__ -#include -#include - - -#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)) { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#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 -#else -#ifdef CONFIG_DEV_RDONLY - CERROR("obd_fail_loc=%x, fail write operation on %s\n", - id, ll_bdevname(dev.value)); - dev_set_rdonly(dev, 2); -#else - CERROR("obd_fail_loc=%x, can't fail write operation on %s\n", - id, ll_bdevname(dev.value)); -#endif -#endif - /* We set FAIL_ONCE because we never "un-fail" a device */ - obd_fail_loc |= OBD_FAILED | OBD_FAIL_ONCE; - } -} - -#endif /* __KERNEL__ */ - -#define OBD_ALLOC(ptr, size) \ -do { \ - void *lptr; \ - int s = (size); \ - (ptr) = lptr = kmalloc(s, GFP_KERNEL); \ - if (lptr == NULL) { \ - CERROR("kmalloc of '" #ptr "' (%d bytes) failed " \ - "at %s:%d\n", s, __FILE__, __LINE__); \ - } else { \ - int obd_curmem; \ - memset(lptr, 0, s); \ - atomic_add(s, &obd_memory); \ - obd_curmem = atomic_read(&obd_memory); \ - if (obd_curmem > obd_memmax) \ - obd_memmax = obd_curmem; \ - CDEBUG(D_MALLOC, "kmalloced '" #ptr "': %d at %p " \ - "(tot %d)\n", s, lptr, obd_curmem); \ - } \ -} while (0) - -#ifdef CONFIG_DEBUG_SLAB -#define POISON(lptr, c, s) do {} while (0) -#else -#define POISON(lptr, c, s) memset(lptr, c, s) -#endif - -#define OBD_FREE(ptr, size) \ -do { \ - void *lptr = (ptr); \ - int s = (size); \ - LASSERT(lptr); \ - POISON(lptr, 0x5a, s); \ - kfree(lptr); \ - atomic_sub(s, &obd_memory); \ - CDEBUG(D_MALLOC, "kfreed '" #ptr "': %d at %p (tot %d).\n", \ - s, lptr, atomic_read(&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/kernel_patches/README b/lustre/kernel_patches/README deleted file mode 100644 index 7d4c4b6..0000000 --- a/lustre/kernel_patches/README +++ /dev/null @@ -1,708 +0,0 @@ -Patch management scripts -Andrew Morton -18 October 2002 - -This is a description of a bunch of shell scripts which I use for -managing kernel patches. They are quite powerful. They can be used on -projects other than the linux kernel. They are easy to use, and fast. - -You end up doing a ton of recompiling with these scripts, because -you're pushing and popping all the time. ccache takes away the pain of -all that. http://ccache.samba.org/ - be sure to put the cache -directory on the same fs as where you're working so that ccache can use -hardlinks. - -The key philosophical concept is that your primary output is patches. -Not ".c" files, not ".h" files. But patches. So patches are the -first-class object here. - -Installation -============ - -You place all the scripts somewhere in your path, or in -/usr/lib/patch-scripts. - -Terminology -=========== - -The patch scripts require three special directories called "pc", -"patches" and "txt". - -If the environment variable PATCHSCRIPTS is set, it is taken to to be -the directory in which those three directories reside. Typically, it -would be a relative pathname. So - - setenv PATCHSCRIPTS ./i-put-them-here - -would tell the patch scripts to look in ./i-put-them-here/pc, etc. - -If PATCHSCRIPTS is not set, and the directory ./patch-scripts is -present then the patch scripts will us ./patch-scripts/pc/, -./patch-scripts/patches/ and ./patch-scripts/txt/. - -Otherwise, the patch scripts use ./pc, ./patches and ./txt. - -In this document, the symbol $P is used to describe the directory which -holds the pc/, patches/ and txt/ directories, as determined by the -above search. - -It is expected that $P will always expand to a relative path. - -Concepts -======== - -All work occurs with a single directory tree. All commands are invoked -within the root of that tree. The scripts manage a "stack" of patches. - -Each patch is a changeset against the base tree plus the preceding patches. - -All patches are listed, in order, in the file ./series. You manage the -series file. - -Any currently-applied patches are described in the file -./applied-patches. The patch scripts manage this file. - -Each patch affects a number of files in the tree. These files are -listed in a "patch control" file. These .pc files live in the -directory $P/pc/ - -Patches are placed in the directory $P/patches/ - -Documentation for the patches is placed in $P/txt/ - -So for a particular patch "my-first-patch" the following will exist: - -- An entry "my-first-patch.patch" in ./series - -- An entry "my-first-patch" in ./applied-patches (if it's currently applied) - -- A file $P/pc/my-first-patch.pc which contains the names of the - files which my-first-patch modifies, adds or removes - -- A file $P/txt/my-first-patch.txt which contains the patch's - changelog. - -- A file $P/patches/my-first-patch.patch, which is the output of the - patch scripts. - -Operation -========= - -When a patch "my-patch" is applied with apatch, or with pushpatch -(which calls apatch), all the affected files (from $P/pc/my-patch.pc) -are copied to files with ~my-patch appended. So if $P/pc/my-patch.pc -contained - - kernel/sched.c - fs/inode.c - -then apatch will copy those files into kernel/sched.c~my-patch and -fs/inode.c~my-patch. It will then apply the patch to kernel/sched.c -and fs/inode.c - -When a diff is regenerated by refpatch (which calls mpatch), the diff -is made between kernel/sched.c and kernel/sched.c~my-patch. How do the -scripts know to use "~my-patch"? Because my-patch is the current -topmost patch. It's the last line in ./applied-patches. - -In this way, the whole thing is stackable. If you have four patches -applied, say "patch-1", "patch-2", "patch-3" and "patch-4", and if -patch-2 and patch-4 both touch kernel/sched.c then you will have: - - kernel/sched.c~patch-2 Original copy, before patch-2 - kernel/sched.c~patch-4 Copy before patch-4. Contains changes - from patch-2 - kernel/sched.c Current working copy. Contains changes - from patch-4. - -This means that your diff headers contain "~patch-name" in them, which -is convenient documentation. - -Walkthrough -=========== - -Let's start. - -Go into /usr/src/linux (or wherever) - - mkdir pc patches txt - -Now let's generate a patch - - fpatch my-patch kernel/sched.c - -OK, we've copied kernel/sched.c to kernel/sched.c~my-patch. We've -appended "my-patch" to ./applied-patches and we've put "kernel/sched.c" -into the patch control file, pc/my-patch.pc. - - Now edit kernel/sched.c a bit. - -Now we're ready to document the patch - - Now write txt/my-patch.txt - -Now generate the patch - - refpatch - -This will generate patches/my-patch.patch. Take a look. - -Now remove the patch - - poppatch - -applied-patches is now empty, and the patch is removed. - -Now let's add a file to my-patch and then generate my-second-patch: - - Add "my-patch.patch" to ./series (no blank lines in that file please) - - pushpatch - -OK, the patch is applied again. Let's add another file - - fpatch kernel/printk.c - -Note that here we gave fpatch a single argument. So rather than -opening a new patch, it adds kernel/printk.c to the existing topmost -patch. That's my-patch. - - Edit kernel/printk.c - -Refresh my-patch (you end up running refpatch a lot) - - refpatch - -Now start a second patch: - - fpatch my-second-patch kernel/sched.c - -Now take a look at applied-patches. Also do an `ls kernel/sched*'. - - Edit kernel/sched.c, to make some changes for my-second-patch - -Generate my-second-patch: - - refpatch - -Take a look in patches/my-second-patch.patch - -Don't forget to add "my-second-patch.patch" to the series file. - -And remove both patches: - - poppatch - poppatch - - -That's pretty much it, really. - - -Command reference -================= - -Generally, where any of these commands take a "patch-name", that can be -of the form txt/patch-name.txt, patch-name.pc, just patch-name or -whatever. The scripts will strip off a leading "txt/", "patches/" or -"pc/" and any trailing extension. This is so you can do - - apatch patches/a - -to conveniently use shell tabbing to select patch names. - - - -added-by-patch - - Some internal thing. - -apatch [-f] patch-name - - This is the low-level function which adds patches. It does the - copying into ~-files and updates the applied-patches file. It - applies the actual patch. - - apatch will do a patch --dry-run first and will refuse to apply the - patch if the dryrun fails. - - So when you are getting rejects you do this: - - pushpatch # This fails, due to rejects. Drat. - apatch -f patch-name # Force the patch - (or) pushpatch -f # Force the patch - - OK, you've now applied patch-name, but you have rejects. Go fix - those up and do - - refpatch - - And you're ready to move on. - -combine-series output-file - - It incrementally combinediffs all the patches in series to make a - complete patch for the series. Requires combinediff frmo patchutils. - - See http://cyberelk.net/tim/patchutils/ (Don't download the - "experimental" patchutils - it seems to only have half of the - commands in it. Go for "stable") - -cvs-take-patch - - I forget. - -export_patch - - export the patches listed in ./series to a set of files which - are named in such a way that the sort order is the same as the - order of the series file. - - Usage: export_patch directory [prefix] - - Example: - - Suppose ./series contains - - mango.patch - orange.patch - banana.patch - apple.patch - pear.patch - - export_patch ../mypatches fruit - - The patches would be copied to - - ../mypatches/p00001_fruit_mango.patch - ../mypatches/p00002_fruit_orange.patch - ../mypatches/p00003_fruit_banana.patch - ../mypatches/p00003_fruit_banana.patch - ../mypatches/p00003_fruit_banana.patch - - Named in this way, someone may easily apply them: - - cat mypatches/p*fruit* | patch -p1 - - If prefix is omitted, the patchnames will be transformed - such that "original.patch" becomes "pXXXXX_original.patch". - -fpatch [patch-name] foo.c - - If patch-name is given, fpatch will start a new patch which - modifies (or adds, or removes) the single file foo.c. It updates - ./applied-patches and creates pc/patch-name.pc. fpatch will copy - foo.c to foo.c~patch-name in preparation for edits of foo.c. - - If patch-name is not given then fpatch will add foo.c to the - current topmost patch. It will add "foo.c" to $P/pc/$(toppatch).pc. - It will copy foo.c to foo.c~$(toppatch). - -import_patch - - Imports a set of patch files, creating $P/pc, $P/txt, $P/patches and - ./series as necessary. It also creates $P/txt/*.txt by stripping - off the top of the patches (and removes any diffstat output it finds, - so that it can eat refpatch output and export_patch output.) The - imported patch names are appended to the series file. - - In creating the $P/txt/*.txt files, mail headers are stripped with - formail, preserving the "From:" and "Subject:" lines. "DESC" and - "EDESC" markers are added if they are not already present, using the - "From:" and "Subject:" lines for the DESC portion, if they are present. - (See "patchdesc" command, below, for more on these markers.) - - Also, it can rename the patch file as it is imported by stripping out - a pattern. This is useful if, as often is the case, you have patch - sets with filenames designed to help sort the patches into the correct - order, such as "p001_xxx_funky_stuff.patch" you can have it automatically - renamed to funky_stuff.patch on import, and let the series file manage - the ordering. - - Import_patch will uncompress patches (*.Z, *.bz2, *.gz) as necessary. - - Usage: - - import_patch [-p pattern] patchfile ... - - Example: - - % ls ../fruit/p*patch - ../fruit/p00001_northern_apple.patch - ../fruit/p00001_tropical_mango.patch - ../fruit/p00002_northern_pear.patch - ../fruit/p00002_tropical_orange.patch - ../fruit/p00003_tropical_banana.patch - % import_patch -p 'p[0-9]*_tropical_' ../fruit/p*tropical* - Recreated pc/mango.pc - Recreated pc/orange.pc - Recreated pc/banana.pc - % import_patch -p 'p[0-9]*_northern_' ../fruit/p*northern* - Recreated pc/apple.pc - Recreated pc/pear.pc - - Then you can "pushpatch; refpatch" 5 times. - -inpatch - - List the names of ths files which are affected by the current - topmost patch. - - This is basically - - cat pc/$(toppatch).pc - -mpatch - - A low-level thing to generate patches - -new-kernel - - Some thing I use for importing a new kernel from kernel.org - -p0-2-p1 - - Internal thing to convert patch -p0 form into patch -p1 - -patchdesc - - Generates a single-line description of a patch. - - The txt/my-patch.txt files have the following format: - - - DESC - some short description - EDESC - - The long description - - - I use - - patchdesc $(cat series) - - to generate short-form summaries of the patch series. - -patchfns - - Internal utilities - -pcpatch - - Standalone tool to generate a .pc file from a patch. - - Say someone sends you "his-patch.diff". What you do is: - - cp ~/his-patch.diff patches/his-patch.patch - pcpatch his-patch - - This generates $P/pc/his-patch.pc and you're all set. Add - "his-patch.patch" to ./series in the right place and start pushing. - -p_diff - - I forget - -poppatch - - Remove one or more patches from the current stack. This command - does *not* use the series file. It works purely against - applied-patches. - - Usage: - - poppatch - Remove the topmost patch - poppatch 10 - Remove ten patches - poppatch some-patch-name[.patch] - Remove patches until "some-patch-name" is top patch - -pstatus - - Shows status of patches - - Usage: - pstatus [patchfile ...] - - One line per patch is output showing: - 1: Patch number in the series file - 2: Whether the patch is currently applied - 3: Name of patch - 4: Status of the patch (needs pcpatch, changelog, refpatch) - - If no patchfiles are specified, $P/patches/*.patch - are assumed. - - Caveats: - A patch set which contains separate patches to add a file - and modify that same file may give spurious "Needs refpatch" - status for the patch which adds the file or the topmost patch. - -ptkdiff - - Two modes: - - ptkdiff - - - Run tkdiff against all the file affected - by $(toppatch). The diff is only for the changes made - by the top patch! ie: it's between "filename" and - "filename~toppatch-name". - - ptkdiff filename - - Just run tkdiff against that file, - showing the changes which are due to toppatch. - -pushpatch [-f] - - Apply the next patch, from the series file. - - This consults ./applied-patches to find out the top patch, then - consults ./series to find the next patch. And pushes it. - - pushpatch - - Apply the next patch - - pushpatch 10 - - Apply the next ten patches - - pushpatch some-patch-name - - Keep pushing patches until "some-patch-name" is toppatch - - pushpatch -f - - Push the next patch, ignoring rejects. - -refpatch - - regnerates the topmost patch. Reads all the affected files - from pc/$(toppatch).pc and diffs them against their tilde-files. - - Also pastes into the patch your patch documentation and - generates a diffstat summary. - -removed-by-patch - - Some thing. - -rename-patch - - CVS rename for patches. - -rolled-up-patch - - Bit of a hack. Is designed to generate a rolled-up diff of all - currently-applied patches. But it requires a ../linux-2.x.y tree to - diff against. Needs to be redone. - -rpatch - - Internal command - -split-patch - - Some thing someone write to split patches up. I don't use it. - -tag-series - - Assuming you keep pc/*, patches/* and txt/* under CVS revision - control, tag-series allows you to tag a patchset's individual - components. I use - - tag-series s2_5_44-mm3 pc/2.5.44-mm3-series - - which will attach the cvs tag "s2_5_44-mm3" to every .pc, .patch - and .txt file which is mentioned in the series file - "pc/2.5.44-mm3-series". - - It will also tag pc/2.5.44-mm3-series, which is a bit redundant - given that I use a different series file for each patchset release.. - - -toppatch - - Print the name of the topmost patch. From ./applied-patches - -touched-by-patch patch-filename - - List the names of files which are affected by a diff. - -unitdiff.py - - Rasmus Andersen's script to convert a diff into minimum-context - form. This form has a better chance of applying if you're getting - nasty rejects. But patch can and will make mistakes when fed - small-context input. - - -Work Practices -============== - -I keep the kernel tree, the $P/pc/, $P/patches/ and $P/txt/ contents under -CVS control. This is important... - -I have several "series" files. I keep these in $P/pc/foo-series and use - - ln -s pc/foo-series series - -when I'm working on foo. - -If someone sends me a patch I'll do: - - cp ~/whatever patches/his-patch.patch - pcpatch his-patch - apatch his-patch - - If apatch fails then run `apatch -f his-patch' and fix the rejects. - - refpatch - - to clean up any fuzz. - - poppatch - cvs add pc/his-patch.pc patches/his-patch.patch - cvs commit pc patches - - Now edit ./series and place "his-patch.patch" in the appropriate place. - - -If you're working on a particular patch (say, "dud-patch") and you -balls something up, just run: - - refpatch # Generate the crap patch - poppatch # Remove it all - rm patches/dud-patch.patch - cvs up patches/dud-patch.patch - -and all is well. - - -Getting updates from Linus -========================== - -What I do is to grab the latest -bk diff from -http://www.kernel.org/pub/linux/kernel/people/dwmw2/bk-2.5/ -and do: - - gzip -d < cs > patches/linus.patch - pcpatch linus - apatch linus | grep diff - - Now fix up all the files which got deleted, - because there's something wrong with bitkeeper diffs: - - cvs up -ko - - apatch linus - $EDITOR linus/linus.txt - - Add the changeset number to txt/linus.txt - - refpatch - poppatch - - Now add "linus.patch" as the first entry in your ./series file and - start pushing your other patches on top of that. - -BUGS -==== - -Tons and tons. The scripts are fragile, the error handling is ungraceful and -if you do something silly you can end up in a pickle. - -Generally the scripts are very careful to not wreck your files or your -patches. But they can get the ./applied-patches and ~-files into an -awkward state. - -Usually you can sort it out by copying the ~-files back onto the originals -and removing the last line from ./applied-patches. Or do a "refpatch ; -poppatch ; rm patches/troublesome-patch.patch ; cvs up patches". - -If it's really bad, just blow away the entire tree and do a new CVS checkout. - - -Working on non-kernel projects -============================== - -Well it's the same thing. Say you've downloaded a copy of util-linux -and you want to make a change: - - cd /usr/src - tar xvfz ~/util-linux.tar.gz - cd util-linux - mkdir pc patches txt - fpatch my-patch sys-utils/rdev.c - fpatch sys-utils/ipcs.8 - - refpatch - - -How to balls things up -====================== - -Well here's one way. Suppose you have 20 patches applied, and three of -them (say, "p1", "p6" and "p11") all modify "foo.c". - -Now you go and change foo.c. - -Well, to which patch does that change belong? You need to decide. -Let's say you decide "p6". - -If you run `refpatch' when "p11" is toppatch then you lose. The diff -went into p11. - -What you can do is: - -1: - poppatch p6 - - refpatch - pushpatch p11 - - - (See why ccache is looking good?) - -or - -2: - - - poppatch p6 - refpatch - - -Another good way of ballsing up is to cheat. Say "oh I just want to make -this one-line change". And "oh, and this one". - -Now you're getting in a mess. It's much, much better to just use the system: - - fpatch junk file1 - fpatch file2 - - - refpatch - poppatch - rm pc/junk.pc patches/junk.patch - -Merging with -mm kernels -======================== - -Haven't tried this, but it should work: - -- Grab all the patches from broken-out/, place them in your $P/patches/ - -- Copy my series file into ./series (or $P/pc/akpm-series and symlink it) - -- pushpatch 99 - -And you're off and running. The nice thing about this is that you can -send me incremental diffs to diffs which I already have. - -Or whatever. I'm fairly handy with diffs nowadays. Rejects are -expected. I just prefer to have "one concept per diff". - diff --git a/lustre/kernel_patches/patches/dev_read_only.patch b/lustre/kernel_patches/patches/dev_read_only.patch deleted file mode 100644 index bac5ebf..0000000 --- a/lustre/kernel_patches/patches/dev_read_only.patch +++ /dev/null @@ -1,73 +0,0 @@ - - - - 0 files changed - ---- linux-2.4.18-17.8.0/drivers/block/blkpg.c~dev_read_only 2002-12-06 14:52:29.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/drivers/block/blkpg.c 2002-12-06 14:52:29.000000000 -0800 -@@ -297,3 +297,38 @@ int blk_ioctl(kdev_t dev, unsigned int c - } - - EXPORT_SYMBOL(blk_ioctl); -+ -+#define NUM_DEV_NO_WRITE 16 -+static int dev_no_write[NUM_DEV_NO_WRITE]; -+ -+/* -+ * Debug code for turning block devices "read-only" (will discard writes -+ * silently). This is for filesystem crash/recovery testing. -+ */ -+void dev_set_rdonly(kdev_t dev, int no_write) -+{ -+ if (dev) { -+ printk(KERN_WARNING "Turning device %s read-only\n", -+ bdevname(dev)); -+ dev_no_write[no_write] = 0xdead0000 + dev; -+ } -+} -+ -+int dev_check_rdonly(kdev_t dev) { -+ int i; -+ -+ for (i = 0; i < NUM_DEV_NO_WRITE; i++) { -+ if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 && -+ dev == (dev_no_write[i] & 0xffff)) -+ return 1; -+ } -+ return 0; -+} -+ -+void dev_clear_rdonly(int no_write) { -+ dev_no_write[no_write] = 0; -+} -+ -+EXPORT_SYMBOL(dev_set_rdonly); -+EXPORT_SYMBOL(dev_check_rdonly); -+EXPORT_SYMBOL(dev_clear_rdonly); ---- linux-2.4.18-17.8.0/drivers/block/loop.c~dev_read_only 2002-12-06 14:52:29.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/drivers/block/loop.c 2002-12-06 14:52:29.000000000 -0800 -@@ -491,6 +491,9 @@ static int loop_make_request(request_que - spin_unlock_irq(&lo->lo_lock); - - if (rw == WRITE) { -+ if (dev_check_rdonly(rbh->b_rdev)) -+ goto err; -+ - if (lo->lo_flags & LO_FLAGS_READ_ONLY) - goto err; - } else if (rw == READA) { ---- linux-2.4.18-17.8.0/drivers/ide/ide-disk.c~dev_read_only 2002-12-06 14:52:29.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/drivers/ide/ide-disk.c 2002-12-06 14:52:29.000000000 -0800 -@@ -557,6 +557,10 @@ static ide_startstop_t lba_48_rw_disk (i - */ - static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) - { -+ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { -+ ide_end_request(1, HWGROUP(drive)); -+ return ide_stopped; -+ } - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl,IDE_CONTROL_REG); - - -_ diff --git a/lustre/kernel_patches/patches/dev_read_only_hp.patch b/lustre/kernel_patches/patches/dev_read_only_hp.patch deleted file mode 100644 index b2cf6f0..0000000 --- a/lustre/kernel_patches/patches/dev_read_only_hp.patch +++ /dev/null @@ -1,77 +0,0 @@ - drivers/block/blkpg.c | 38 ++++++++++++++++++++++++++++++++++++++ - drivers/block/loop.c | 5 +++++ - drivers/ide/ide-disk.c | 6 ++++++ - 3 files changed, 49 insertions(+) - ---- linux-2.4.19-hp2_pnnl2/drivers/block/blkpg.c~dev_read_only_hp Sun Jan 19 18:51:12 2003 -+++ linux-2.4.19-hp2_pnnl2-root/drivers/block/blkpg.c Sun Jan 19 18:52:28 2003 -@@ -310,6 +310,42 @@ int blk_ioctl(kdev_t dev, unsigned int c - - EXPORT_SYMBOL(blk_ioctl); - -+ -+#define NUM_DEV_NO_WRITE 16 -+static int dev_no_write[NUM_DEV_NO_WRITE]; -+ -+/* -+ * Debug code for turning block devices "read-only" (will discard writes -+ * silently). This is for filesystem crash/recovery testing. -+ */ -+void dev_set_rdonly(kdev_t dev, int no_write) -+{ -+ if (dev) { -+ printk(KERN_WARNING "Turning device %s read-only\n", -+ bdevname(dev)); -+ dev_no_write[no_write] = 0xdead0000 + dev; -+ } -+} -+ -+int dev_check_rdonly(kdev_t dev) { -+ int i; -+ -+ for (i = 0; i < NUM_DEV_NO_WRITE; i++) { -+ if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 && -+ dev == (dev_no_write[i] & 0xffff)) -+ return 1; -+ } -+ return 0; -+} -+ -+void dev_clear_rdonly(int no_write) { -+ dev_no_write[no_write] = 0; -+} -+ -+EXPORT_SYMBOL(dev_set_rdonly); -+EXPORT_SYMBOL(dev_check_rdonly); -+EXPORT_SYMBOL(dev_clear_rdonly); -+ - /** - * get_last_sector() - * ---- linux-2.4.19-hp2_pnnl2/drivers/block/loop.c~dev_read_only_hp Sun Jan 19 18:51:12 2003 -+++ linux-2.4.19-hp2_pnnl2-root/drivers/block/loop.c Sun Jan 19 18:51:12 2003 -@@ -474,6 +474,9 @@ static int loop_make_request(request_que - spin_unlock_irq(&lo->lo_lock); - - if (rw == WRITE) { -+ if (dev_check_rdonly(rbh->b_rdev)) -+ goto err; -+ - if (lo->lo_flags & LO_FLAGS_READ_ONLY) - goto err; - } else if (rw == READA) { ---- linux-2.4.19-hp2_pnnl2/drivers/ide/ide-disk.c~dev_read_only_hp Sun Jan 19 18:51:12 2003 -+++ linux-2.4.19-hp2_pnnl2-root/drivers/ide/ide-disk.c Sun Jan 19 18:51:12 2003 -@@ -551,6 +551,10 @@ static ide_startstop_t lba_48_rw_disk (i - */ - static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) - { -+ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { -+ ide_end_request(1, HWGROUP(drive)); -+ return ide_stopped; -+ } - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl,IDE_CONTROL_REG); - - -_ diff --git a/lustre/kernel_patches/patches/exports.patch b/lustre/kernel_patches/patches/exports.patch deleted file mode 100644 index 716c156..0000000 --- a/lustre/kernel_patches/patches/exports.patch +++ /dev/null @@ -1,57 +0,0 @@ - - - - fs/ext3/Makefile | 2 ++ - fs/ext3/super.c | 2 +- - include/linux/fs.h | 1 + - kernel/ksyms.c | 5 +++++ - 4 files changed, 9 insertions(+), 1 deletion(-) - ---- linux-2.4.19-hp2_pnnl2/fs/ext3/Makefile~exports Sun Jan 19 18:52:38 2003 -+++ linux-2.4.19-hp2_pnnl2-root/fs/ext3/Makefile Sun Jan 19 18:52:38 2003 -@@ -9,6 +9,8 @@ - - O_TARGET := ext3.o - -+export-objs := super.o -+ - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o - obj-m := $(O_TARGET) ---- linux-2.4.19-hp2_pnnl2/fs/ext3/super.c~exports Sun Jan 19 18:52:38 2003 -+++ linux-2.4.19-hp2_pnnl2-root/fs/ext3/super.c Sun Jan 19 18:52:38 2003 -@@ -1744,7 +1744,7 @@ static void __exit exit_ext3_fs(void) - unregister_filesystem(&ext3_fs_type); - } - --EXPORT_NO_SYMBOLS; -+EXPORT_SYMBOL(ext3_bread); - - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); - MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); ---- linux-2.4.19-hp2_pnnl2/include/linux/fs.h~exports Sun Jan 19 18:52:38 2003 -+++ linux-2.4.19-hp2_pnnl2-root/include/linux/fs.h Sun Jan 19 18:52:38 2003 -@@ -1020,6 +1020,7 @@ extern int unregister_filesystem(struct - extern struct vfsmount *kern_mount(struct file_system_type *); - extern int may_umount(struct vfsmount *); - extern long do_mount(char *, char *, char *, unsigned long, void *); -+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); - extern void umount_tree(struct vfsmount *); - - #define kern_umount mntput ---- linux-2.4.19-hp2_pnnl2/kernel/ksyms.c~exports Sun Jan 19 18:52:38 2003 -+++ linux-2.4.19-hp2_pnnl2-root/kernel/ksyms.c Sun Jan 19 18:52:38 2003 -@@ -308,6 +308,11 @@ EXPORT_SYMBOL(dcache_dir_fsync); - EXPORT_SYMBOL(dcache_readdir); - EXPORT_SYMBOL(dcache_dir_ops); - -+/* lustre */ -+EXPORT_SYMBOL(panic_notifier_list); -+EXPORT_SYMBOL(pagecache_lock_cacheline); -+EXPORT_SYMBOL(do_kern_mount); -+ - /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ - EXPORT_SYMBOL(default_llseek); - EXPORT_SYMBOL(dentry_open); - -_ diff --git a/lustre/kernel_patches/patches/exports_hp.patch b/lustre/kernel_patches/patches/exports_hp.patch deleted file mode 100644 index 0222b46..0000000 --- a/lustre/kernel_patches/patches/exports_hp.patch +++ /dev/null @@ -1,56 +0,0 @@ - - - - fs/ext3/Makefile | 2 ++ - fs/ext3/super.c | 2 +- - include/linux/fs.h | 1 + - kernel/ksyms.c | 4 ++++ - 4 files changed, 9 insertions(+), 1 deletion(-) - ---- linux-2.4.19-hp2_pnnl2/fs/ext3/Makefile~exports Sun Jan 19 18:52:38 2003 -+++ linux-2.4.19-hp2_pnnl2-root/fs/ext3/Makefile Sun Jan 19 18:52:38 2003 -@@ -9,6 +9,8 @@ - - O_TARGET := ext3.o - -+export-objs := super.o -+ - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o - obj-m := $(O_TARGET) ---- linux-2.4.19-hp2_pnnl2/fs/ext3/super.c~exports Sun Jan 19 18:52:38 2003 -+++ linux-2.4.19-hp2_pnnl2-root/fs/ext3/super.c Sun Jan 19 18:52:38 2003 -@@ -1744,7 +1744,7 @@ static void __exit exit_ext3_fs(void) - unregister_filesystem(&ext3_fs_type); - } - --EXPORT_NO_SYMBOLS; -+EXPORT_SYMBOL(ext3_bread); - - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); - MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); ---- linux-2.4.19-hp2_pnnl2/include/linux/fs.h~exports Sun Jan 19 18:52:38 2003 -+++ linux-2.4.19-hp2_pnnl2-root/include/linux/fs.h Sun Jan 19 18:52:38 2003 -@@ -1020,6 +1020,7 @@ extern int unregister_filesystem(struct - extern struct vfsmount *kern_mount(struct file_system_type *); - extern int may_umount(struct vfsmount *); - extern long do_mount(char *, char *, char *, unsigned long, void *); -+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); - extern void umount_tree(struct vfsmount *); - - #define kern_umount mntput ---- linux-2.4.19-hp2_pnnl2/kernel/ksyms.c~exports Sun Jan 19 18:52:38 2003 -+++ linux-2.4.19-hp2_pnnl2-root/kernel/ksyms.c Sun Jan 19 18:52:38 2003 -@@ -308,6 +308,10 @@ EXPORT_SYMBOL(dcache_dir_fsync); - EXPORT_SYMBOL(dcache_readdir); - EXPORT_SYMBOL(dcache_dir_ops); - -+/* lustre */ -+EXPORT_SYMBOL(pagecache_lock_cacheline); -+EXPORT_SYMBOL(do_kern_mount); -+ - /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ - EXPORT_SYMBOL(default_llseek); - EXPORT_SYMBOL(dentry_open); - -_ diff --git a/lustre/kernel_patches/patches/ext3-xattr-2.5.patch b/lustre/kernel_patches/patches/ext3-xattr-2.5.patch deleted file mode 100644 index 4179839..0000000 --- a/lustre/kernel_patches/patches/ext3-xattr-2.5.patch +++ /dev/null @@ -1,2690 +0,0 @@ -# This is a BitKeeper generated patch for the following project: -# Project Name: Linux kernel tree -# This patch format is intended for GNU patch command version 2.5 or higher. -# This patch includes the following deltas: -# ChangeSet 1.809 -> 1.810 -# fs/ext3/Makefile 1.4 -> 1.5 -# include/linux/ext3_jbd.h 1.5 -> 1.6 -# fs/ext3/ialloc.c 1.17 -> 1.18 -# fs/ext3/symlink.c 1.3 -> 1.4 -# fs/Makefile 1.42 -> 1.43 -# fs/ext3/namei.c 1.22 -> 1.23 -# include/linux/ext3_fs.h 1.11 -> 1.12 -# fs/Config.in 1.39 -> 1.40 -# fs/ext3/inode.c 1.42 -> 1.43 -# fs/Config.help 1.21 -> 1.22 -# fs/ext3/super.c 1.33 -> 1.34 -# fs/ext3/file.c 1.9 -> 1.10 -# (new) -> 1.1 fs/ext3/xattr.h -# (new) -> 1.1 include/linux/mbcache.h -# (new) -> 1.1 fs/ext3/xattr.c -# (new) -> 1.1 fs/mbcache.c -# (new) -> 1.1 fs/ext3/xattr_user.c -# -# The following is the BitKeeper ChangeSet Log -# -------------------------------------------- -# 02/10/20 braam@clusterfs.com 1.810 -# xattrs for UML bk repository -# -------------------------------------------- -# -diff -Nru a/fs/Config.help b/fs/Config.help ---- a/fs/Config.help Sun Dec 8 02:49:56 2002 -+++ b/fs/Config.help Sun Dec 8 02:49:56 2002 -@@ -154,6 +154,13 @@ - of your root partition (the one containing the directory /) cannot - be compiled as a module, and so this may be dangerous. - -+CONFIG_EXT3_FS_XATTR -+ Extended attributes are name:value pairs associated with inodes by -+ the kernel or by users (see the attr(5) manual page, or visit -+ for details). -+ -+ If unsure, say N. -+ - CONFIG_JBD - This is a generic journaling layer for block devices. It is - currently used by the ext3 file system, but it could also be used to -diff -Nru a/fs/Config.in b/fs/Config.in ---- a/fs/Config.in Sun Dec 8 02:49:56 2002 -+++ b/fs/Config.in Sun Dec 8 02:49:56 2002 -@@ -27,6 +27,7 @@ - dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL - - tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS -+dep_mbool ' Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS - # CONFIG_JBD could be its own option (even modular), but until there are - # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS - # dep_tristate ' Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS -@@ -180,6 +181,17 @@ - define_tristate CONFIG_ZISOFS_FS $CONFIG_ISO9660_FS - else - define_tristate CONFIG_ZISOFS_FS n -+fi -+ -+# Meta block cache for Extended Attributes (ext2/ext3) -+if [ "$CONFIG_EXT2_FS_XATTR" = "y" -o "$CONFIG_EXT3_FS_XATTR" = "y" ]; then -+ if [ "$CONFIG_EXT2_FS" = "y" -o "$CONFIG_EXT3_FS" = "y" ]; then -+ define_tristate CONFIG_FS_MBCACHE y -+ else -+ if [ "$CONFIG_EXT2_FS" = "m" -o "$CONFIG_EXT3_FS" = "m" ]; then -+ define_tristate CONFIG_FS_MBCACHE m -+ fi -+ fi - fi - - mainmenu_option next_comment -diff -Nru a/fs/Makefile b/fs/Makefile ---- a/fs/Makefile Sun Dec 8 02:49:56 2002 -+++ b/fs/Makefile Sun Dec 8 02:49:56 2002 -@@ -6,7 +6,7 @@ - # - - export-objs := open.o dcache.o buffer.o bio.o inode.o dquot.o mpage.o aio.o \ -- fcntl.o read_write.o dcookies.o -+ fcntl.o read_write.o dcookies.o mbcache.o - - obj-y := open.o read_write.o devices.o file_table.o buffer.o \ - bio.o super.o block_dev.o char_dev.o stat.o exec.o pipe.o \ -@@ -29,6 +29,8 @@ - obj-y += binfmt_script.o - - obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o -+ -+obj-$(CONFIG_FS_MBCACHE) += mbcache.o - - obj-$(CONFIG_QUOTA) += dquot.o - obj-$(CONFIG_QFMT_V1) += quota_v1.o -diff -Nru a/fs/ext3/Makefile b/fs/ext3/Makefile ---- a/fs/ext3/Makefile Sun Dec 8 02:49:56 2002 -+++ b/fs/ext3/Makefile Sun Dec 8 02:49:56 2002 -@@ -7,4 +7,10 @@ - ext3-objs := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o hash.o - -+export-objs += xattr.o -+ -+ifeq ($(CONFIG_EXT3_FS_XATTR),y) -+ext3-objs += xattr.o xattr_user.o -+endif -+ - include $(TOPDIR)/Rules.make -diff -Nru a/fs/ext3/file.c b/fs/ext3/file.c ---- a/fs/ext3/file.c Sun Dec 8 02:49:56 2002 -+++ b/fs/ext3/file.c Sun Dec 8 02:49:56 2002 -@@ -23,7 +23,7 @@ - #include - #include - #include --#include -+#include "xattr.h" - - /* - * Called when an inode is released. Note that this is different -@@ -98,5 +98,9 @@ - struct inode_operations ext3_file_inode_operations = { - .truncate = ext3_truncate, - .setattr = ext3_setattr, -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, - }; - -diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c ---- a/fs/ext3/ialloc.c Sun Dec 8 02:49:56 2002 -+++ b/fs/ext3/ialloc.c Sun Dec 8 02:49:56 2002 -@@ -25,6 +25,8 @@ - #include - #include - -+#include "xattr.h" -+ - /* - * ialloc.c contains the inodes allocation and deallocation routines - */ -@@ -118,6 +120,7 @@ - * as writing the quota to disk may need the lock as well. - */ - DQUOT_INIT(inode); -+ ext3_xattr_delete_inode(handle, inode); - DQUOT_FREE_INODE(inode); - DQUOT_DROP(inode); - -diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c ---- a/fs/ext3/inode.c Sun Dec 8 02:49:56 2002 -+++ b/fs/ext3/inode.c Sun Dec 8 02:49:56 2002 -@@ -42,6 +42,18 @@ - */ - #undef SEARCH_FROM_ZERO - -+/* -+ * Test whether an inode is a fast symlink. -+ */ -+static inline int ext3_inode_is_fast_symlink(struct inode *inode) -+{ -+ int ea_blocks = EXT3_I(inode)->i_file_acl ? -+ (inode->i_sb->s_blocksize >> 9) : 0; -+ -+ return (S_ISLNK(inode->i_mode) && -+ inode->i_blocks - ea_blocks == 0); -+} -+ - /* The ext3 forget function must perform a revoke if we are freeing data - * which has been journaled. Metadata (eg. indirect blocks) must be - * revoked in all cases. -@@ -51,7 +63,7 @@ - * still needs to be revoked. - */ - --static int ext3_forget(handle_t *handle, int is_metadata, -+int ext3_forget(handle_t *handle, int is_metadata, - struct inode *inode, struct buffer_head *bh, - int blocknr) - { -@@ -167,9 +179,7 @@ - { - handle_t *handle; - -- if (is_bad_inode(inode) || -- inode->i_ino == EXT3_ACL_IDX_INO || -- inode->i_ino == EXT3_ACL_DATA_INO) -+ if (is_bad_inode(inode)) - goto no_delete; - - lock_kernel(); -@@ -1979,6 +1989,8 @@ - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return; -+ if (ext3_inode_is_fast_symlink(inode)) -+ return; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - return; - -@@ -2130,8 +2142,6 @@ - struct ext3_group_desc * gdp; - - if ((inode->i_ino != EXT3_ROOT_INO && -- inode->i_ino != EXT3_ACL_IDX_INO && -- inode->i_ino != EXT3_ACL_DATA_INO && - inode->i_ino != EXT3_JOURNAL_INO && - inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) || - inode->i_ino > le32_to_cpu( -@@ -2263,10 +2273,7 @@ - - brelse (iloc.bh); - -- if (inode->i_ino == EXT3_ACL_IDX_INO || -- inode->i_ino == EXT3_ACL_DATA_INO) -- /* Nothing to do */ ; -- else if (S_ISREG(inode->i_mode)) { -+ if (S_ISREG(inode->i_mode)) { - inode->i_op = &ext3_file_inode_operations; - inode->i_fop = &ext3_file_operations; - if (ext3_should_writeback_data(inode)) -@@ -2277,18 +2284,20 @@ - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; - } else if (S_ISLNK(inode->i_mode)) { -- if (!inode->i_blocks) -+ if (ext3_inode_is_fast_symlink(inode)) - inode->i_op = &ext3_fast_symlink_inode_operations; - else { -- inode->i_op = &page_symlink_inode_operations; -+ inode->i_op = &ext3_symlink_inode_operations; - if (ext3_should_writeback_data(inode)) - inode->i_mapping->a_ops = &ext3_writeback_aops; - else - inode->i_mapping->a_ops = &ext3_aops; - } -- } else -+ } else { -+ inode->i_op = &ext3_special_inode_operations; - init_special_inode(inode, inode->i_mode, - le32_to_cpu(iloc.raw_inode->i_block[0])); -+ } - if (ei->i_flags & EXT3_SYNC_FL) - inode->i_flags |= S_SYNC; - if (ei->i_flags & EXT3_APPEND_FL) -diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c ---- a/fs/ext3/namei.c Sun Dec 8 02:49:56 2002 -+++ b/fs/ext3/namei.c Sun Dec 8 02:49:56 2002 -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include "xattr.h" - - - /* -@@ -1654,7 +1655,7 @@ - if (IS_DIRSYNC(dir)) - handle->h_sync = 1; - -- inode = ext3_new_inode (handle, dir, S_IFDIR); -+ inode = ext3_new_inode (handle, dir, S_IFDIR | mode); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; -@@ -1662,7 +1663,6 @@ - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; - inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; -- inode->i_blocks = 0; - dir_block = ext3_bread (handle, inode, 0, 1, &err); - if (!dir_block) { - inode->i_nlink--; /* is this nlink == 0? */ -@@ -1689,9 +1689,6 @@ - BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata"); - ext3_journal_dirty_metadata(handle, dir_block); - brelse (dir_block); -- inode->i_mode = S_IFDIR | mode; -- if (dir->i_mode & S_ISGID) -- inode->i_mode |= S_ISGID; - ext3_mark_inode_dirty(handle, inode); - err = ext3_add_entry (handle, dentry, inode); - if (err) { -@@ -2068,7 +2065,7 @@ - goto out_stop; - - if (l > sizeof (EXT3_I(inode)->i_data)) { -- inode->i_op = &page_symlink_inode_operations; -+ inode->i_op = &ext3_symlink_inode_operations; - if (ext3_should_writeback_data(inode)) - inode->i_mapping->a_ops = &ext3_writeback_aops; - else -@@ -2284,4 +2281,17 @@ - .rmdir = ext3_rmdir, - .mknod = ext3_mknod, - .rename = ext3_rename, -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, - }; -+ -+struct inode_operations ext3_special_inode_operations = { -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, -+}; -+ -+ -diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c ---- a/fs/ext3/super.c Sun Dec 8 02:49:56 2002 -+++ b/fs/ext3/super.c Sun Dec 8 02:49:56 2002 -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include "xattr.h" - - #ifdef CONFIG_JBD_DEBUG - static int ext3_ro_after; /* Make fs read-only after this many jiffies */ -@@ -405,6 +406,7 @@ - struct ext3_super_block *es = sbi->s_es; - int i; - -+ ext3_xattr_put_super(sb); - journal_destroy(sbi->s_journal); - if (!(sb->s_flags & MS_RDONLY)) { - EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); -@@ -554,6 +556,7 @@ - int is_remount) - { - unsigned long *mount_options = &sbi->s_mount_opt; -+ - uid_t *resuid = &sbi->s_resuid; - gid_t *resgid = &sbi->s_resgid; - char * this_char; -@@ -566,6 +569,13 @@ - continue; - if ((value = strchr (this_char, '=')) != NULL) - *value++ = 0; -+#ifdef CONFIG_EXT3_FS_XATTR -+ if (!strcmp (this_char, "user_xattr")) -+ set_opt (*mount_options, XATTR_USER); -+ else if (!strcmp (this_char, "nouser_xattr")) -+ clear_opt (*mount_options, XATTR_USER); -+ else -+#endif - if (!strcmp (this_char, "bsddf")) - clear_opt (*mount_options, MINIX_DF); - else if (!strcmp (this_char, "nouid32")) { -@@ -982,6 +992,12 @@ - sbi->s_mount_opt = 0; - sbi->s_resuid = EXT3_DEF_RESUID; - sbi->s_resgid = EXT3_DEF_RESGID; -+ -+ /* Default extended attribute flags */ -+#ifdef CONFIG_EXT3_FS_XATTR -+ set_opt(sbi->s_mount_opt, XATTR_USER); -+#endif -+ - if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) - goto out_fail; - -@@ -1820,7 +1836,10 @@ - - static int __init init_ext3_fs(void) - { -- int err = init_inodecache(); -+ int err = init_ext3_xattr(); -+ if (err) -+ return err; -+ err = init_inodecache(); - if (err) - goto out1; - err = register_filesystem(&ext3_fs_type); -@@ -1830,6 +1849,7 @@ - out: - destroy_inodecache(); - out1: -+ exit_ext3_xattr(); - return err; - } - -@@ -1837,6 +1857,7 @@ - { - unregister_filesystem(&ext3_fs_type); - destroy_inodecache(); -+ exit_ext3_xattr(); - } - - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); -diff -Nru a/fs/ext3/symlink.c b/fs/ext3/symlink.c ---- a/fs/ext3/symlink.c Sun Dec 8 02:49:56 2002 -+++ b/fs/ext3/symlink.c Sun Dec 8 02:49:56 2002 -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include "xattr.h" - - static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen) - { -@@ -33,7 +34,20 @@ - return vfs_follow_link(nd, (char*)ei->i_data); - } - -+struct inode_operations ext3_symlink_inode_operations = { -+ .readlink = page_readlink, -+ .follow_link = page_follow_link, -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, -+}; -+ - struct inode_operations ext3_fast_symlink_inode_operations = { -- .readlink = ext3_readlink, /* BKL not held. Don't need */ -+ .readlink = ext3_readlink, /* BKL not held. Don't need */ - .follow_link = ext3_follow_link, /* BKL not held. Don't need */ -+ .setxattr = ext3_setxattr, -+ .getxattr = ext3_getxattr, -+ .listxattr = ext3_listxattr, -+ .removexattr = ext3_removexattr, - }; -diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/fs/ext3/xattr.c Sun Dec 8 02:49:56 2002 -@@ -0,0 +1,1127 @@ -+/* -+ * linux/fs/ext3/xattr.c -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ * -+ * Fix by Harrison Xing . -+ * Ext3 code with a lot of help from Eric Jarman . -+ * Extended attributes for symlinks and special files added per -+ * suggestion of Luka Renko . -+ */ -+ -+/* -+ * Extended attributes are stored on disk blocks allocated outside of -+ * any inode. The i_file_acl field is then made to point to this allocated -+ * block. If all extended attributes of an inode are identical, these -+ * inodes may share the same extended attribute block. Such situations -+ * are automatically detected by keeping a cache of recent attribute block -+ * numbers and hashes over the block's contents in memory. -+ * -+ * -+ * Extended attribute block layout: -+ * -+ * +------------------+ -+ * | header | -+ * ¦ entry 1 | | -+ * | entry 2 | | growing downwards -+ * | entry 3 | v -+ * | four null bytes | -+ * | . . . | -+ * | value 1 | ^ -+ * | value 3 | | growing upwards -+ * | value 2 | | -+ * +------------------+ -+ * -+ * The block header is followed by multiple entry descriptors. These entry -+ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD -+ * byte boundaries. The entry descriptors are sorted by attribute name, -+ * so that two extended attribute blocks can be compared efficiently. -+ * -+ * Attribute values are aligned to the end of the block, stored in -+ * no specific order. They are also padded to EXT3_XATTR_PAD byte -+ * boundaries. No additional gaps are left between them. -+ * -+ * Locking strategy -+ * ---------------- -+ * The VFS holdsinode->i_sem semaphore when any of the xattr inode -+ * operations are called, so we are guaranteed that only one -+ * processes accesses extended attributes of an inode at any time. -+ * -+ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that -+ * only a single process is modifying an extended attribute block, even -+ * if the block is shared among inodes. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "xattr.h" -+ -+#define EXT3_EA_USER "user." -+ -+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data)) -+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr)) -+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1) -+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) -+ -+#ifdef EXT3_XATTR_DEBUG -+# define ea_idebug(inode, f...) do { \ -+ printk(KERN_DEBUG "inode %s:%ld: ", \ -+ kdevname(inode->i_dev), inode->i_ino); \ -+ printk(f); \ -+ printk("\n"); \ -+ } while (0) -+# define ea_bdebug(bh, f...) do { \ -+ printk(KERN_DEBUG "block %s:%ld: ", \ -+ kdevname(bh->b_dev), bh->b_blocknr); \ -+ printk(f); \ -+ printk("\n"); \ -+ } while (0) -+#else -+# define ea_idebug(f...) -+# define ea_bdebug(f...) -+#endif -+ -+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *, -+ struct ext3_xattr_header *); -+ -+static int ext3_xattr_cache_insert(struct buffer_head *); -+static struct buffer_head *ext3_xattr_cache_find(struct inode *, -+ struct ext3_xattr_header *); -+static void ext3_xattr_cache_remove(struct buffer_head *); -+static void ext3_xattr_rehash(struct ext3_xattr_header *, -+ struct ext3_xattr_entry *); -+ -+static struct mb_cache *ext3_xattr_cache; -+ -+/* -+ * If a file system does not share extended attributes among inodes, -+ * we should not need the ext3_xattr_sem semaphore. However, the -+ * filesystem may still contain shared blocks, so we always take -+ * the lock. -+ */ -+ -+static DECLARE_MUTEX(ext3_xattr_sem); -+static struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX]; -+static rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED; -+ -+int -+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler) -+{ -+ int error = -EINVAL; -+ -+ if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) { -+ write_lock(&ext3_handler_lock); -+ if (!ext3_xattr_handlers[name_index-1]) { -+ ext3_xattr_handlers[name_index-1] = handler; -+ error = 0; -+ } -+ write_unlock(&ext3_handler_lock); -+ } -+ return error; -+} -+ -+void -+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler) -+{ -+ if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) { -+ write_lock(&ext3_handler_lock); -+ ext3_xattr_handlers[name_index-1] = NULL; -+ write_unlock(&ext3_handler_lock); -+ } -+} -+ -+static inline const char * -+strcmp_prefix(const char *a, const char *a_prefix) -+{ -+ while (*a_prefix && *a == *a_prefix) { -+ a++; -+ a_prefix++; -+ } -+ return *a_prefix ? NULL : a; -+} -+ -+/* -+ * Decode the extended attribute name, and translate it into -+ * the name_index and name suffix. -+ */ -+static inline struct ext3_xattr_handler * -+ext3_xattr_resolve_name(const char **name) -+{ -+ struct ext3_xattr_handler *handler = NULL; -+ int i; -+ -+ if (!*name) -+ return NULL; -+ read_lock(&ext3_handler_lock); -+ for (i=0; iprefix); -+ if (n) { -+ handler = ext3_xattr_handlers[i]; -+ *name = n; -+ break; -+ } -+ } -+ } -+ read_unlock(&ext3_handler_lock); -+ return handler; -+} -+ -+static inline struct ext3_xattr_handler * -+ext3_xattr_handler(int name_index) -+{ -+ struct ext3_xattr_handler *handler = NULL; -+ if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) { -+ read_lock(&ext3_handler_lock); -+ handler = ext3_xattr_handlers[name_index-1]; -+ read_unlock(&ext3_handler_lock); -+ } -+ return handler; -+} -+ -+/* -+ * Inode operation getxattr() -+ * -+ * dentry->d_inode->i_sem down -+ */ -+ssize_t -+ext3_getxattr(struct dentry *dentry, const char *name, -+ void *buffer, size_t size) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -EOPNOTSUPP; -+ return handler->get(inode, name, buffer, size); -+} -+ -+/* -+ * Inode operation listxattr() -+ * -+ * dentry->d_inode->i_sem down -+ */ -+ssize_t -+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size) -+{ -+ return ext3_xattr_list(dentry->d_inode, buffer, size); -+} -+ -+/* -+ * Inode operation setxattr() -+ * -+ * dentry->d_inode->i_sem down -+ */ -+int -+ext3_setxattr(struct dentry *dentry, const char *name, -+ void *value, size_t size, int flags) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ if (size == 0) -+ value = ""; /* empty EA, do not remove */ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -EOPNOTSUPP; -+ return handler->set(inode, name, value, size, flags); -+} -+ -+/* -+ * Inode operation removexattr() -+ * -+ * dentry->d_inode->i_sem down -+ */ -+int -+ext3_removexattr(struct dentry *dentry, const char *name) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -EOPNOTSUPP; -+ return handler->set(inode, name, NULL, 0, XATTR_REPLACE); -+} -+ -+/* -+ * ext3_xattr_get() -+ * -+ * Copy an extended attribute into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext3_xattr_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t buffer_size) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_entry *entry; -+ unsigned int block, size; -+ char *end; -+ int name_len, error; -+ -+ ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", -+ name_index, name, buffer, (long)buffer_size); -+ -+ if (name == NULL) -+ return -EINVAL; -+ if (!EXT3_I(inode)->i_file_acl) -+ return -ENODATA; -+ block = EXT3_I(inode)->i_file_acl; -+ ea_idebug(inode, "reading block %d", block); -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(inode->i_sb, "ext3_xattr_get", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* find named attribute */ -+ name_len = strlen(name); -+ -+ error = -ERANGE; -+ if (name_len > 255) -+ goto cleanup; -+ entry = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (name_index == entry->e_name_index && -+ name_len == entry->e_name_len && -+ memcmp(name, entry->e_name, name_len) == 0) -+ goto found; -+ entry = next; -+ } -+ /* Check the remaining name entries */ -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ entry = next; -+ } -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ error = -ENODATA; -+ goto cleanup; -+found: -+ /* check the buffer size */ -+ if (entry->e_value_block != 0) -+ goto bad_block; -+ size = le32_to_cpu(entry->e_value_size); -+ if (size > inode->i_sb->s_blocksize || -+ le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize) -+ goto bad_block; -+ -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ if (buffer) { -+ error = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ /* return value of attribute */ -+ memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs), -+ size); -+ } -+ error = size; -+ -+cleanup: -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * ext3_xattr_list() -+ * -+ * Copy a list of attribute names into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_entry *entry; -+ unsigned int block, size = 0; -+ char *buf, *end; -+ int error; -+ -+ ea_idebug(inode, "buffer=%p, buffer_size=%ld", -+ buffer, (long)buffer_size); -+ -+ if (!EXT3_I(inode)->i_file_acl) -+ return 0; -+ block = EXT3_I(inode)->i_file_acl; -+ ea_idebug(inode, "reading block %d", block); -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(inode->i_sb, "ext3_xattr_list", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* compute the size required for the list of attribute names */ -+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); -+ entry = EXT3_XATTR_NEXT(entry)) { -+ struct ext3_xattr_handler *handler; -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ -+ handler = ext3_xattr_handler(entry->e_name_index); -+ if (handler) { -+ size += handler->list(NULL, inode, entry->e_name, -+ entry->e_name_len) + 1; -+ } -+ } -+ -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ if (!buffer) { -+ error = size; -+ goto cleanup; -+ } else { -+ error = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ } -+ -+ /* list the attribute names */ -+ buf = buffer; -+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); -+ entry = EXT3_XATTR_NEXT(entry)) { -+ struct ext3_xattr_handler *handler; -+ -+ handler = ext3_xattr_handler(entry->e_name_index); -+ if (handler) { -+ buf += handler->list(buf, inode, entry->e_name, -+ entry->e_name_len); -+ *buf++ = '\0'; -+ } -+ } -+ error = size; -+ -+cleanup: -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is -+ * not set, set it. -+ */ -+static void ext3_xattr_update_super_block(handle_t *handle, -+ struct super_block *sb) -+{ -+ if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) -+ return; -+ -+ lock_super(sb); -+ ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); -+ EXT3_SB(sb)->s_es->s_feature_compat |= -+ cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR); -+ sb->s_dirt = 1; -+ ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); -+ unlock_super(sb); -+} -+ -+/* -+ * ext3_xattr_set() -+ * -+ * Create, replace or remove an extended attribute for this inode. Buffer -+ * is NULL to remove an existing extended attribute, and non-NULL to -+ * either replace an existing extended attribute, or create a new extended -+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE -+ * specify that an extended attribute must exist and must not exist -+ * previous to the call, respectively. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+int -+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, -+ const char *name, const void *value, size_t value_len, int flags) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_header *header = NULL; -+ struct ext3_xattr_entry *here, *last; -+ unsigned int name_len; -+ int min_offs = sb->s_blocksize, not_found = 1, free, error; -+ char *end; -+ -+ /* -+ * header -- Points either into bh, or to a temporarily -+ * allocated buffer. -+ * here -- The named entry found, or the place for inserting, within -+ * the block pointed to by header. -+ * last -- Points right after the last named entry within the block -+ * pointed to by header. -+ * min_offs -- The offset of the first value (values are aligned -+ * towards the end of the block). -+ * end -- Points right after the block pointed to by header. -+ */ -+ -+ ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld", -+ name_index, name, value, (long)value_len); -+ -+ if (IS_RDONLY(inode)) -+ return -EROFS; -+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -+ return -EPERM; -+ if (value == NULL) -+ value_len = 0; -+ if (name == NULL) -+ return -EINVAL; -+ name_len = strlen(name); -+ if (name_len > 255 || value_len > sb->s_blocksize) -+ return -ERANGE; -+ down(&ext3_xattr_sem); -+ -+ if (EXT3_I(inode)->i_file_acl) { -+ /* The inode already has an extended attribute block. */ -+ int block = EXT3_I(inode)->i_file_acl; -+ -+ bh = sb_bread(sb, block); -+ error = -EIO; -+ if (!bh) -+ goto cleanup; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), -+ le32_to_cpu(HDR(bh)->h_refcount)); -+ header = HDR(bh); -+ end = bh->b_data + bh->b_size; -+ if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ header->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(sb, "ext3_xattr_set", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* Find the named attribute. */ -+ here = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(here)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (!here->e_value_block && here->e_value_size) { -+ int offs = le16_to_cpu(here->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ not_found = name_index - here->e_name_index; -+ if (!not_found) -+ not_found = name_len - here->e_name_len; -+ if (!not_found) -+ not_found = memcmp(name, here->e_name,name_len); -+ if (not_found <= 0) -+ break; -+ here = next; -+ } -+ last = here; -+ /* We still need to compute min_offs and last. */ -+ while (!IS_LAST_ENTRY(last)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (!last->e_value_block && last->e_value_size) { -+ int offs = le16_to_cpu(last->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ last = next; -+ } -+ -+ /* Check whether we have enough space left. */ -+ free = min_offs - ((char*)last - (char*)header) - sizeof(__u32); -+ } else { -+ /* We will use a new extended attribute block. */ -+ free = sb->s_blocksize - -+ sizeof(struct ext3_xattr_header) - sizeof(__u32); -+ here = last = NULL; /* avoid gcc uninitialized warning. */ -+ } -+ -+ if (not_found) { -+ /* Request to remove a nonexistent attribute? */ -+ error = -ENODATA; -+ if (flags & XATTR_REPLACE) -+ goto cleanup; -+ error = 0; -+ if (value == NULL) -+ goto cleanup; -+ else -+ free -= EXT3_XATTR_LEN(name_len); -+ } else { -+ /* Request to create an existing attribute? */ -+ error = -EEXIST; -+ if (flags & XATTR_CREATE) -+ goto cleanup; -+ if (!here->e_value_block && here->e_value_size) { -+ unsigned int size = le32_to_cpu(here->e_value_size); -+ -+ if (le16_to_cpu(here->e_value_offs) + size > -+ sb->s_blocksize || size > sb->s_blocksize) -+ goto bad_block; -+ free += EXT3_XATTR_SIZE(size); -+ } -+ } -+ free -= EXT3_XATTR_SIZE(value_len); -+ error = -ENOSPC; -+ if (free < 0) -+ goto cleanup; -+ -+ /* Here we know that we can set the new attribute. */ -+ -+ if (header) { -+ if (header->h_refcount == cpu_to_le32(1)) { -+ ea_bdebug(bh, "modifying in-place"); -+ ext3_xattr_cache_remove(bh); -+ error = ext3_journal_get_write_access(handle, bh); -+ if (error) -+ goto cleanup; -+ } else { -+ int offset; -+ -+ ea_bdebug(bh, "cloning"); -+ header = kmalloc(bh->b_size, GFP_KERNEL); -+ error = -ENOMEM; -+ if (header == NULL) -+ goto cleanup; -+ memcpy(header, HDR(bh), bh->b_size); -+ header->h_refcount = cpu_to_le32(1); -+ offset = (char *)header - bh->b_data; -+ here = ENTRY((char *)here + offset); -+ last = ENTRY((char *)last + offset); -+ } -+ } else { -+ /* Allocate a buffer where we construct the new block. */ -+ header = kmalloc(sb->s_blocksize, GFP_KERNEL); -+ error = -ENOMEM; -+ if (header == NULL) -+ goto cleanup; -+ memset(header, 0, sb->s_blocksize); -+ end = (char *)header + sb->s_blocksize; -+ header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC); -+ header->h_blocks = header->h_refcount = cpu_to_le32(1); -+ last = here = ENTRY(header+1); -+ } -+ -+ if (not_found) { -+ /* Insert the new name. */ -+ int size = EXT3_XATTR_LEN(name_len); -+ int rest = (char *)last - (char *)here; -+ memmove((char *)here + size, here, rest); -+ memset(here, 0, size); -+ here->e_name_index = name_index; -+ here->e_name_len = name_len; -+ memcpy(here->e_name, name, name_len); -+ } else { -+ /* Remove the old value. */ -+ if (!here->e_value_block && here->e_value_size) { -+ char *first_val = (char *)header + min_offs; -+ int offs = le16_to_cpu(here->e_value_offs); -+ char *val = (char *)header + offs; -+ size_t size = EXT3_XATTR_SIZE( -+ le32_to_cpu(here->e_value_size)); -+ memmove(first_val + size, first_val, val - first_val); -+ memset(first_val, 0, size); -+ here->e_value_offs = 0; -+ min_offs += size; -+ -+ /* Adjust all value offsets. */ -+ last = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(last)) { -+ int o = le16_to_cpu(last->e_value_offs); -+ if (!last->e_value_block && o < offs) -+ last->e_value_offs = -+ cpu_to_le16(o + size); -+ last = EXT3_XATTR_NEXT(last); -+ } -+ } -+ if (value == NULL) { -+ /* Remove this attribute. */ -+ if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) { -+ /* This block is now empty. */ -+ error = ext3_xattr_set2(handle, inode, bh,NULL); -+ goto cleanup; -+ } else { -+ /* Remove the old name. */ -+ int size = EXT3_XATTR_LEN(name_len); -+ last = ENTRY((char *)last - size); -+ memmove(here, (char*)here + size, -+ (char*)last - (char*)here); -+ memset(last, 0, size); -+ } -+ } -+ } -+ -+ if (value != NULL) { -+ /* Insert the new value. */ -+ here->e_value_size = cpu_to_le32(value_len); -+ if (value_len) { -+ size_t size = EXT3_XATTR_SIZE(value_len); -+ char *val = (char *)header + min_offs - size; -+ here->e_value_offs = -+ cpu_to_le16((char *)val - (char *)header); -+ memset(val + size - EXT3_XATTR_PAD, 0, -+ EXT3_XATTR_PAD); /* Clear the pad bytes. */ -+ memcpy(val, value, value_len); -+ } -+ } -+ ext3_xattr_rehash(header, here); -+ -+ error = ext3_xattr_set2(handle, inode, bh, header); -+ -+cleanup: -+ brelse(bh); -+ if (!(bh && header == HDR(bh))) -+ kfree(header); -+ up(&ext3_xattr_sem); -+ -+ return error; -+} -+ -+/* -+ * Second half of ext3_xattr_set(): Update the file system. -+ */ -+static int -+ext3_xattr_set2(handle_t *handle, struct inode *inode, -+ struct buffer_head *old_bh, struct ext3_xattr_header *header) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct buffer_head *new_bh = NULL; -+ int error; -+ -+ if (header) { -+ new_bh = ext3_xattr_cache_find(inode, header); -+ if (new_bh) { -+ /* -+ * We found an identical block in the cache. -+ * The old block will be released after updating -+ * the inode. -+ */ -+ ea_bdebug(old_bh, "reusing block %ld", -+ new_bh->b_blocknr); -+ -+ error = -EDQUOT; -+ if (DQUOT_ALLOC_BLOCK(inode, 1)) -+ goto cleanup; -+ -+ error = ext3_journal_get_write_access(handle, new_bh); -+ if (error) -+ goto cleanup; -+ HDR(new_bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(new_bh)->h_refcount) + 1); -+ ea_bdebug(new_bh, "refcount now=%d", -+ le32_to_cpu(HDR(new_bh)->h_refcount)); -+ } else if (old_bh && header == HDR(old_bh)) { -+ /* Keep this block. */ -+ new_bh = old_bh; -+ ext3_xattr_cache_insert(new_bh); -+ } else { -+ /* We need to allocate a new block */ -+ int block; -+ int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + -+ EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb); -+ -+ block = ext3_new_block(handle, inode, goal, 0, -+ 0, &error); -+ if (error) -+ goto cleanup; -+ ea_idebug(inode, "creating block %d", block); -+ -+ new_bh = sb_getblk(sb, block); -+ if (!new_bh) { -+getblk_failed: -+ ext3_free_blocks(handle, inode, block, 1); -+ error = -EIO; -+ goto cleanup; -+ } -+ lock_buffer(new_bh); -+ error = ext3_journal_get_create_access(handle, new_bh); -+ if (error) { -+ unlock_buffer(new_bh); -+ goto getblk_failed; -+ } -+ memcpy(new_bh->b_data, header, new_bh->b_size); -+ set_buffer_uptodate(new_bh); -+ unlock_buffer(new_bh); -+ ext3_xattr_cache_insert(new_bh); -+ -+ ext3_xattr_update_super_block(handle, sb); -+ } -+ error = ext3_journal_dirty_metadata(handle, new_bh); -+ if (error) -+ goto cleanup; -+ } -+ -+ /* Update the inode. */ -+ EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0; -+ inode->i_ctime = CURRENT_TIME; -+ ext3_mark_inode_dirty(handle, inode); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ -+ error = 0; -+ if (old_bh && old_bh != new_bh) { -+ /* -+ * If there was an old block, and we are not still using it, -+ * we now release the old block. -+ */ -+ unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount); -+ -+ error = ext3_journal_get_write_access(handle, old_bh); -+ if (error) -+ goto cleanup; -+ if (refcount == 1) { -+ /* Free the old block. */ -+ ea_bdebug(old_bh, "freeing"); -+ ext3_free_blocks(handle, inode, old_bh->b_blocknr, 1); -+ -+ /* ext3_forget() calls bforget() for us, but we -+ let our caller release old_bh, so we need to -+ duplicate the handle before. */ -+ get_bh(old_bh); -+ ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr); -+ } else { -+ /* Decrement the refcount only. */ -+ refcount--; -+ HDR(old_bh)->h_refcount = cpu_to_le32(refcount); -+ DQUOT_FREE_BLOCK(inode, 1); -+ ext3_journal_dirty_metadata(handle, old_bh); -+ ea_bdebug(old_bh, "refcount now=%d", refcount); -+ } -+ } -+ -+cleanup: -+ if (old_bh != new_bh) -+ brelse(new_bh); -+ -+ return error; -+} -+ -+/* -+ * ext3_xattr_delete_inode() -+ * -+ * Free extended attribute resources associated with this inode. This -+ * is called immediately before an inode is freed. -+ */ -+void -+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode) -+{ -+ struct buffer_head *bh; -+ unsigned int block = EXT3_I(inode)->i_file_acl; -+ -+ if (!block) -+ return; -+ down(&ext3_xattr_sem); -+ -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) { -+ ext3_error(inode->i_sb, "ext3_xattr_delete_inode", -+ "inode %ld: block %d read error", inode->i_ino, block); -+ goto cleanup; -+ } -+ ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count))); -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+ ext3_error(inode->i_sb, "ext3_xattr_delete_inode", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ goto cleanup; -+ } -+ ext3_journal_get_write_access(handle, bh); -+ ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ if (HDR(bh)->h_refcount == cpu_to_le32(1)) { -+ ext3_xattr_cache_remove(bh); -+ ext3_free_blocks(handle, inode, block, 1); -+ ext3_forget(handle, 1, inode, bh, block); -+ bh = NULL; -+ } else { -+ HDR(bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ ext3_journal_dirty_metadata(handle, bh); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ DQUOT_FREE_BLOCK(inode, 1); -+ } -+ EXT3_I(inode)->i_file_acl = 0; -+ -+cleanup: -+ brelse(bh); -+ up(&ext3_xattr_sem); -+} -+ -+/* -+ * ext3_xattr_put_super() -+ * -+ * This is called when a file system is unmounted. -+ */ -+void -+ext3_xattr_put_super(struct super_block *sb) -+{ -+ mb_cache_shrink(ext3_xattr_cache, sb->s_bdev); -+} -+ -+/* -+ * ext3_xattr_cache_insert() -+ * -+ * Create a new entry in the extended attribute cache, and insert -+ * it unless such an entry is already in the cache. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+static int -+ext3_xattr_cache_insert(struct buffer_head *bh) -+{ -+ __u32 hash = le32_to_cpu(HDR(bh)->h_hash); -+ struct mb_cache_entry *ce; -+ int error; -+ -+ ce = mb_cache_entry_alloc(ext3_xattr_cache); -+ if (!ce) -+ return -ENOMEM; -+ error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash); -+ if (error) { -+ mb_cache_entry_free(ce); -+ if (error == -EBUSY) { -+ ea_bdebug(bh, "already in cache (%d cache entries)", -+ atomic_read(&ext3_xattr_cache->c_entry_count)); -+ error = 0; -+ } -+ } else { -+ ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash, -+ atomic_read(&ext3_xattr_cache->c_entry_count)); -+ mb_cache_entry_release(ce); -+ } -+ return error; -+} -+ -+/* -+ * ext3_xattr_cmp() -+ * -+ * Compare two extended attribute blocks for equality. -+ * -+ * Returns 0 if the blocks are equal, 1 if they differ, and -+ * a negative error number on errors. -+ */ -+static int -+ext3_xattr_cmp(struct ext3_xattr_header *header1, -+ struct ext3_xattr_header *header2) -+{ -+ struct ext3_xattr_entry *entry1, *entry2; -+ -+ entry1 = ENTRY(header1+1); -+ entry2 = ENTRY(header2+1); -+ while (!IS_LAST_ENTRY(entry1)) { -+ if (IS_LAST_ENTRY(entry2)) -+ return 1; -+ if (entry1->e_hash != entry2->e_hash || -+ entry1->e_name_len != entry2->e_name_len || -+ entry1->e_value_size != entry2->e_value_size || -+ memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len)) -+ return 1; -+ if (entry1->e_value_block != 0 || entry2->e_value_block != 0) -+ return -EIO; -+ if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), -+ (char *)header2 + le16_to_cpu(entry2->e_value_offs), -+ le32_to_cpu(entry1->e_value_size))) -+ return 1; -+ -+ entry1 = EXT3_XATTR_NEXT(entry1); -+ entry2 = EXT3_XATTR_NEXT(entry2); -+ } -+ if (!IS_LAST_ENTRY(entry2)) -+ return 1; -+ return 0; -+} -+ -+/* -+ * ext3_xattr_cache_find() -+ * -+ * Find an identical extended attribute block. -+ * -+ * Returns a pointer to the block found, or NULL if such a block was -+ * not found or an error occurred. -+ */ -+static struct buffer_head * -+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header) -+{ -+ __u32 hash = le32_to_cpu(header->h_hash); -+ struct mb_cache_entry *ce; -+ -+ if (!header->h_hash) -+ return NULL; /* never share */ -+ ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); -+ ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_bdev, hash); -+ while (ce) { -+ struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block); -+ -+ if (!bh) { -+ ext3_error(inode->i_sb, "ext3_xattr_cache_find", -+ "inode %ld: block %ld read error", -+ inode->i_ino, (unsigned long) ce->e_block); -+ } else if (le32_to_cpu(HDR(bh)->h_refcount) > -+ EXT3_XATTR_REFCOUNT_MAX) { -+ ea_idebug(inode, "block %ld refcount %d>%d", -+ (unsigned long) ce->e_block, -+ le32_to_cpu(HDR(bh)->h_refcount), -+ EXT3_XATTR_REFCOUNT_MAX); -+ } else if (!ext3_xattr_cmp(header, HDR(bh))) { -+ ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count))); -+ mb_cache_entry_release(ce); -+ return bh; -+ } -+ brelse(bh); -+ ce = mb_cache_entry_find_next(ce, 0, inode->i_bdev, hash); -+ } -+ return NULL; -+} -+ -+/* -+ * ext3_xattr_cache_remove() -+ * -+ * Remove the cache entry of a block from the cache. Called when a -+ * block becomes invalid. -+ */ -+static void -+ext3_xattr_cache_remove(struct buffer_head *bh) -+{ -+ struct mb_cache_entry *ce; -+ -+ ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev, -+ bh->b_blocknr); -+ if (ce) { -+ ea_bdebug(bh, "removing (%d cache entries remaining)", -+ atomic_read(&ext3_xattr_cache->c_entry_count)-1); -+ mb_cache_entry_free(ce); -+ } else -+ ea_bdebug(bh, "no cache entry"); -+} -+ -+#define NAME_HASH_SHIFT 5 -+#define VALUE_HASH_SHIFT 16 -+ -+/* -+ * ext3_xattr_hash_entry() -+ * -+ * Compute the hash of an extended attribute. -+ */ -+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header, -+ struct ext3_xattr_entry *entry) -+{ -+ __u32 hash = 0; -+ char *name = entry->e_name; -+ int n; -+ -+ for (n=0; n < entry->e_name_len; n++) { -+ hash = (hash << NAME_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^ -+ *name++; -+ } -+ -+ if (entry->e_value_block == 0 && entry->e_value_size != 0) { -+ __u32 *value = (__u32 *)((char *)header + -+ le16_to_cpu(entry->e_value_offs)); -+ for (n = (le32_to_cpu(entry->e_value_size) + -+ EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) { -+ hash = (hash << VALUE_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^ -+ le32_to_cpu(*value++); -+ } -+ } -+ entry->e_hash = cpu_to_le32(hash); -+} -+ -+#undef NAME_HASH_SHIFT -+#undef VALUE_HASH_SHIFT -+ -+#define BLOCK_HASH_SHIFT 16 -+ -+/* -+ * ext3_xattr_rehash() -+ * -+ * Re-compute the extended attribute hash value after an entry has changed. -+ */ -+static void ext3_xattr_rehash(struct ext3_xattr_header *header, -+ struct ext3_xattr_entry *entry) -+{ -+ struct ext3_xattr_entry *here; -+ __u32 hash = 0; -+ -+ ext3_xattr_hash_entry(header, entry); -+ here = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(here)) { -+ if (!here->e_hash) { -+ /* Block is not shared if an entry's hash value == 0 */ -+ hash = 0; -+ break; -+ } -+ hash = (hash << BLOCK_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^ -+ le32_to_cpu(here->e_hash); -+ here = EXT3_XATTR_NEXT(here); -+ } -+ header->h_hash = cpu_to_le32(hash); -+} -+ -+#undef BLOCK_HASH_SHIFT -+ -+int __init -+init_ext3_xattr(void) -+{ -+ int err; -+ -+ err = ext3_xattr_register(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler); -+ if (err) -+ return err; -+ ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL, -+ sizeof(struct mb_cache_entry) + -+ sizeof(struct mb_cache_entry_index), 1, 6); -+ if (!ext3_xattr_cache) { -+ ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+void -+exit_ext3_xattr(void) -+{ -+ if (ext3_xattr_cache) -+ mb_cache_destroy(ext3_xattr_cache); -+ ext3_xattr_cache = NULL; -+ ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, &ext3_xattr_user_handler); -+} -+ -diff -Nru a/fs/ext3/xattr.h b/fs/ext3/xattr.h ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/fs/ext3/xattr.h Sun Dec 8 02:49:56 2002 -@@ -0,0 +1,133 @@ -+/* -+ File: fs/ext3/xattr.h -+ -+ On-disk format of extended attributes for the ext3 filesystem. -+ -+ (C) 2001 Andreas Gruenbacher, -+*/ -+ -+#include -+#include -+ -+/* Magic value in attribute blocks */ -+#define EXT3_XATTR_MAGIC 0xEA020000 -+ -+/* Maximum number of references to one attribute block */ -+#define EXT3_XATTR_REFCOUNT_MAX 1024 -+ -+/* Name indexes */ -+#define EXT3_XATTR_INDEX_MAX 10 -+#define EXT3_XATTR_INDEX_USER 1 -+#define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS 2 -+#define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT 3 -+ -+struct ext3_xattr_header { -+ __u32 h_magic; /* magic number for identification */ -+ __u32 h_refcount; /* reference count */ -+ __u32 h_blocks; /* number of disk blocks used */ -+ __u32 h_hash; /* hash value of all attributes */ -+ __u32 h_reserved[4]; /* zero right now */ -+}; -+ -+struct ext3_xattr_entry { -+ __u8 e_name_len; /* length of name */ -+ __u8 e_name_index; /* attribute name index */ -+ __u16 e_value_offs; /* offset in disk block of value */ -+ __u32 e_value_block; /* disk block attribute is stored on (n/i) */ -+ __u32 e_value_size; /* size of attribute value */ -+ __u32 e_hash; /* hash value of name and value */ -+ char e_name[0]; /* attribute name */ -+}; -+ -+#define EXT3_XATTR_PAD_BITS 2 -+#define EXT3_XATTR_PAD (1<e_name_len)) ) -+#define EXT3_XATTR_SIZE(size) \ -+ (((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND) -+ -+# ifdef CONFIG_EXT3_FS_XATTR -+ -+struct ext3_xattr_handler { -+ char *prefix; -+ size_t (*list)(char *list, struct inode *inode, const char *name, -+ int name_len); -+ int (*get)(struct inode *inode, const char *name, void *buffer, -+ size_t size); -+ int (*set)(struct inode *inode, const char *name, const void *buffer, -+ size_t size, int flags); -+}; -+ -+extern int ext3_xattr_register(int, struct ext3_xattr_handler *); -+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *); -+ -+extern int ext3_setxattr(struct dentry *, const char *, void *, size_t, int); -+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t); -+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); -+extern int ext3_removexattr(struct dentry *, const char *); -+ -+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t); -+extern int ext3_xattr_list(struct inode *, char *, size_t); -+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int); -+ -+extern void ext3_xattr_delete_inode(handle_t *, struct inode *); -+extern void ext3_xattr_put_super(struct super_block *); -+ -+extern int init_ext3_xattr(void); -+extern void exit_ext3_xattr(void); -+ -+# else /* CONFIG_EXT3_FS_XATTR */ -+# define ext3_setxattr NULL -+# define ext3_getxattr NULL -+# define ext3_listxattr NULL -+# define ext3_removexattr NULL -+ -+static inline int -+ext3_xattr_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t size, int flags) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int -+ext3_xattr_list(struct inode *inode, void *buffer, size_t size, int flags) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int -+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, -+ const char *name, const void *value, size_t size, int flags) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline void -+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode) -+{ -+} -+ -+static inline void -+ext3_xattr_put_super(struct super_block *sb) -+{ -+} -+ -+static inline int -+init_ext3_xattr(void) -+{ -+ return 0; -+} -+ -+static inline void -+exit_ext3_xattr(void) -+{ -+} -+ -+# endif /* CONFIG_EXT3_FS_XATTR */ -+ -+extern struct ext3_xattr_handler ext3_xattr_user_handler; -diff -Nru a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/fs/ext3/xattr_user.c Sun Dec 8 02:49:56 2002 -@@ -0,0 +1,99 @@ -+/* -+ * linux/fs/ext3/xattr_user.c -+ * Handler for extended user attributes. -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "xattr.h" -+ -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+# include -+#endif -+ -+#define XATTR_USER_PREFIX "user." -+ -+static size_t -+ext3_xattr_user_list(char *list, struct inode *inode, -+ const char *name, int name_len) -+{ -+ const int prefix_len = sizeof(XATTR_USER_PREFIX)-1; -+ -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return 0; -+ -+ if (list) { -+ memcpy(list, XATTR_USER_PREFIX, prefix_len); -+ memcpy(list+prefix_len, name, name_len); -+ } -+ return prefix_len + name_len; -+} -+ -+static int -+ext3_xattr_user_get(struct inode *inode, const char *name, -+ void *buffer, size_t size) -+{ -+ int error; -+ -+ if (strcmp(name, "") == 0) -+ return -EINVAL; -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return -EOPNOTSUPP; -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+ error = ext3_permission_locked(inode, MAY_READ); -+#else -+ error = permission(inode, MAY_READ); -+#endif -+ if (error) -+ return error; -+ -+ return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name, -+ buffer, size); -+} -+ -+static int -+ext3_xattr_user_set(struct inode *inode, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ handle_t *handle; -+ int error; -+ -+ if (strcmp(name, "") == 0) -+ return -EINVAL; -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return -EOPNOTSUPP; -+ if ( !S_ISREG(inode->i_mode) && -+ (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) -+ return -EPERM; -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+ error = ext3_permission_locked(inode, MAY_WRITE); -+#else -+ error = permission(inode, MAY_WRITE); -+#endif -+ if (error) -+ return error; -+ -+ lock_kernel(); -+ handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name, -+ value, size, flags); -+ ext3_journal_stop(handle, inode); -+ unlock_kernel(); -+ -+ return error; -+} -+ -+struct ext3_xattr_handler ext3_xattr_user_handler = { -+ prefix: XATTR_USER_PREFIX, -+ list: ext3_xattr_user_list, -+ get: ext3_xattr_user_get, -+ set: ext3_xattr_user_set, -+}; -diff -Nru a/fs/mbcache.c b/fs/mbcache.c ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/fs/mbcache.c Sun Dec 8 02:49:56 2002 -@@ -0,0 +1,702 @@ -+/* -+ * linux/fs/mbcache.c -+ * (C) 2001-2002 Andreas Gruenbacher, -+ */ -+ -+/* -+ * Filesystem Meta Information Block Cache (mbcache) -+ * -+ * The mbcache caches blocks of block devices that need to be located -+ * by their device/block number, as well as by other criteria (such -+ * as the block's contents). -+ * -+ * There can only be one cache entry in a cache per device and block number. -+ * Additional indexes need not be unique in this sense. The number of -+ * additional indexes (=other criteria) can be hardwired (at compile time) -+ * or specified at cache create time. -+ * -+ * Each cache entry is of fixed size. An entry may be `valid' or `invalid' -+ * in the cache. A valid entry is in the main hash tables of the cache, -+ * and may also be in the lru list. An invalid entry is not in any hashes -+ * or lists. -+ * -+ * A valid cache entry is only in the lru list if no handles refer to it. -+ * Invalid cache entries will be freed when the last handle to the cache -+ * entry is released. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#ifdef MB_CACHE_DEBUG -+# define mb_debug(f...) do { \ -+ printk(KERN_DEBUG f); \ -+ printk("\n"); \ -+ } while (0) -+#define mb_assert(c) do { if (!(c)) \ -+ printk(KERN_ERR "assertion " #c " failed\n"); \ -+ } while(0) -+#else -+# define mb_debug(f...) do { } while(0) -+# define mb_assert(c) do { } while(0) -+#endif -+#define mb_error(f...) do { \ -+ printk(KERN_ERR f); \ -+ printk("\n"); \ -+ } while(0) -+ -+MODULE_AUTHOR("Andreas Gruenbacher "); -+MODULE_DESCRIPTION("Meta block cache (for extended attributes)"); -+MODULE_LICENSE("GPL"); -+ -+EXPORT_SYMBOL(mb_cache_create); -+EXPORT_SYMBOL(mb_cache_shrink); -+EXPORT_SYMBOL(mb_cache_destroy); -+EXPORT_SYMBOL(mb_cache_entry_alloc); -+EXPORT_SYMBOL(mb_cache_entry_insert); -+EXPORT_SYMBOL(mb_cache_entry_release); -+EXPORT_SYMBOL(mb_cache_entry_takeout); -+EXPORT_SYMBOL(mb_cache_entry_free); -+EXPORT_SYMBOL(mb_cache_entry_dup); -+EXPORT_SYMBOL(mb_cache_entry_get); -+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) -+EXPORT_SYMBOL(mb_cache_entry_find_first); -+EXPORT_SYMBOL(mb_cache_entry_find_next); -+#endif -+ -+ -+/* -+ * Global data: list of all mbcache's, lru list, and a spinlock for -+ * accessing cache data structures on SMP machines. (The lru list is -+ * global across all mbcaches.) -+ */ -+ -+static LIST_HEAD(mb_cache_list); -+static LIST_HEAD(mb_cache_lru_list); -+static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED; -+static struct shrinker *mb_shrinker; -+ -+static inline int -+mb_cache_indexes(struct mb_cache *cache) -+{ -+#ifdef MB_CACHE_INDEXES_COUNT -+ return MB_CACHE_INDEXES_COUNT; -+#else -+ return cache->c_indexes_count; -+#endif -+} -+ -+/* -+ * What the mbcache registers as to get shrunk dynamically. -+ */ -+ -+static int mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask); -+ -+static inline void -+__mb_cache_entry_takeout_lru(struct mb_cache_entry *ce) -+{ -+ if (!list_empty(&ce->e_lru_list)) -+ list_del_init(&ce->e_lru_list); -+} -+ -+ -+static inline void -+__mb_cache_entry_into_lru(struct mb_cache_entry *ce) -+{ -+ list_add(&ce->e_lru_list, &mb_cache_lru_list); -+} -+ -+ -+static inline int -+__mb_cache_entry_in_lru(struct mb_cache_entry *ce) -+{ -+ return (!list_empty(&ce->e_lru_list)); -+} -+ -+ -+/* -+ * Insert the cache entry into all hashes. -+ */ -+static inline void -+__mb_cache_entry_link(struct mb_cache_entry *ce) -+{ -+ struct mb_cache *cache = ce->e_cache; -+ unsigned int bucket; -+ int n; -+ -+ bucket = hash_long((unsigned long)ce->e_bdev + -+ (ce->e_block & 0xffffff), cache->c_bucket_bits); -+ list_add(&ce->e_block_list, &cache->c_block_hash[bucket]); -+ for (n=0; ne_indexes[n].o_key, -+ cache->c_bucket_bits); -+ list_add(&ce->e_indexes[n].o_list, -+ &cache->c_indexes_hash[n][bucket]); -+ } -+} -+ -+ -+/* -+ * Remove the cache entry from all hashes. -+ */ -+static inline void -+__mb_cache_entry_unlink(struct mb_cache_entry *ce) -+{ -+ int n; -+ -+ list_del_init(&ce->e_block_list); -+ for (n = 0; n < mb_cache_indexes(ce->e_cache); n++) -+ list_del(&ce->e_indexes[n].o_list); -+} -+ -+ -+static inline int -+__mb_cache_entry_is_linked(struct mb_cache_entry *ce) -+{ -+ return (!list_empty(&ce->e_block_list)); -+} -+ -+ -+static inline struct mb_cache_entry * -+__mb_cache_entry_read(struct mb_cache_entry *ce) -+{ -+ __mb_cache_entry_takeout_lru(ce); -+ atomic_inc(&ce->e_used); -+ return ce; -+} -+ -+ -+static inline void -+__mb_cache_entry_forget(struct mb_cache_entry *ce) -+{ -+ struct mb_cache *cache = ce->e_cache; -+ -+ mb_assert(atomic_read(&ce->e_used) == 0); -+ atomic_dec(&cache->c_entry_count); -+ if (cache->c_op.free) -+ cache->c_op.free(ce); -+ kmem_cache_free(cache->c_entry_cache, ce); -+} -+ -+ -+static inline void -+__mb_cache_entry_release_unlock(struct mb_cache_entry *ce) -+{ -+ if (atomic_dec_and_test(&ce->e_used)) { -+ if (!__mb_cache_entry_is_linked(ce)) -+ goto forget; -+ __mb_cache_entry_into_lru(ce); -+ } -+ spin_unlock(&mb_cache_spinlock); -+ return; -+forget: -+ spin_unlock(&mb_cache_spinlock); -+ __mb_cache_entry_forget(ce); -+} -+ -+ -+/* -+ * mb_cache_shrink_fn() memory pressure callback -+ * -+ * This function is called by the kernel memory management when memory -+ * gets low. -+ * -+ * @nr_to_scan: Number of objects to scan -+ * @gfp_mask: (ignored) -+ * -+ * Returns the number of objects which are present in the cache. -+ */ -+static int -+mb_cache_shrink_fn(int nr_to_scan, unsigned int gfp_mask) -+{ -+ LIST_HEAD(free_list); -+ struct list_head *l; -+ int count = 0; -+ -+ spin_lock(&mb_cache_spinlock); -+ list_for_each_prev(l, &mb_cache_list) { -+ struct mb_cache *cache = -+ list_entry(l, struct mb_cache, c_cache_list); -+ mb_debug("cache %s (%d)", cache->c_name, -+ atomic_read(&cache->c_entry_count)); -+ count += atomic_read(&cache->c_entry_count); -+ } -+ mb_debug("trying to free %d entries", nr_to_scan); -+ if (nr_to_scan == 0) { -+ spin_unlock(&mb_cache_spinlock); -+ goto out; -+ } -+ while (nr_to_scan && !list_empty(&mb_cache_lru_list)) { -+ struct mb_cache_entry *ce = -+ list_entry(mb_cache_lru_list.prev, -+ struct mb_cache_entry, e_lru_list); -+ list_move(&ce->e_lru_list, &free_list); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ nr_to_scan--; -+ } -+ spin_unlock(&mb_cache_spinlock); -+ l = free_list.prev; -+ while (l != &free_list) { -+ struct mb_cache_entry *ce = list_entry(l, -+ struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ __mb_cache_entry_forget(ce); -+ count--; -+ } -+out: -+ mb_debug("%d remaining entries ", count); -+ return count; -+} -+ -+ -+/* -+ * mb_cache_create() create a new cache -+ * -+ * All entries in one cache are equal size. Cache entries may be from -+ * multiple devices. If this is the first mbcache created, registers -+ * the cache with kernel memory management. Returns NULL if no more -+ * memory was available. -+ * -+ * @name: name of the cache (informal) -+ * @cache_op: contains the callback called when freeing a cache entry -+ * @entry_size: The size of a cache entry, including -+ * struct mb_cache_entry -+ * @indexes_count: number of additional indexes in the cache. Must equal -+ * MB_CACHE_INDEXES_COUNT if the number of indexes is -+ * hardwired. -+ * @bucket_bits: log2(number of hash buckets) -+ */ -+struct mb_cache * -+mb_cache_create(const char *name, struct mb_cache_op *cache_op, -+ size_t entry_size, int indexes_count, int bucket_bits) -+{ -+ int m=0, n, bucket_count = 1 << bucket_bits; -+ struct mb_cache *cache = NULL; -+ -+ if(entry_size < sizeof(struct mb_cache_entry) + -+ indexes_count * sizeof(struct mb_cache_entry_index)) -+ return NULL; -+ -+ cache = kmalloc(sizeof(struct mb_cache) + -+ indexes_count * sizeof(struct list_head), GFP_KERNEL); -+ if (!cache) -+ goto fail; -+ cache->c_name = name; -+ if (cache_op) -+ cache->c_op.free = cache_op->free; -+ else -+ cache->c_op.free = NULL; -+ atomic_set(&cache->c_entry_count, 0); -+ cache->c_bucket_bits = bucket_bits; -+#ifdef MB_CACHE_INDEXES_COUNT -+ mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT); -+#else -+ cache->c_indexes_count = indexes_count; -+#endif -+ cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head), -+ GFP_KERNEL); -+ if (!cache->c_block_hash) -+ goto fail; -+ for (n=0; nc_block_hash[n]); -+ for (m=0; mc_indexes_hash[m] = kmalloc(bucket_count * -+ sizeof(struct list_head), -+ GFP_KERNEL); -+ if (!cache->c_indexes_hash[m]) -+ goto fail; -+ for (n=0; nc_indexes_hash[m][n]); -+ } -+ cache->c_entry_cache = kmem_cache_create(name, entry_size, 0, -+ 0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL); -+ if (!cache->c_entry_cache) -+ goto fail; -+ -+ spin_lock(&mb_cache_spinlock); -+ if (list_empty(&mb_cache_list)) { -+ if (mb_shrinker) { -+ printk(KERN_ERR "%s: already have a shrinker!\n", -+ __FUNCTION__); -+ remove_shrinker(mb_shrinker); -+ } -+ mb_shrinker = set_shrinker(DEFAULT_SEEKS, mb_cache_shrink_fn); -+ } -+ list_add(&cache->c_cache_list, &mb_cache_list); -+ spin_unlock(&mb_cache_spinlock); -+ return cache; -+ -+fail: -+ if (cache) { -+ while (--m >= 0) -+ kfree(cache->c_indexes_hash[m]); -+ if (cache->c_block_hash) -+ kfree(cache->c_block_hash); -+ kfree(cache); -+ } -+ return NULL; -+} -+ -+ -+/* -+ * mb_cache_shrink() -+ * -+ * Removes all cache entires of a device from the cache. All cache entries -+ * currently in use cannot be freed, and thus remain in the cache. All others -+ * are freed. -+ * -+ * @cache: which cache to shrink -+ * @bdev: which device's cache entries to shrink -+ */ -+void -+mb_cache_shrink(struct mb_cache *cache, struct block_device *bdev) -+{ -+ LIST_HEAD(free_list); -+ struct list_head *l; -+ -+ spin_lock(&mb_cache_spinlock); -+ l = mb_cache_lru_list.prev; -+ while (l != &mb_cache_lru_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ if (ce->e_bdev == bdev) { -+ list_move(&ce->e_lru_list, &free_list); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ } -+ } -+ spin_unlock(&mb_cache_spinlock); -+ l = free_list.prev; -+ while (l != &free_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ __mb_cache_entry_forget(ce); -+ } -+} -+ -+ -+/* -+ * mb_cache_destroy() -+ * -+ * Shrinks the cache to its minimum possible size (hopefully 0 entries), -+ * and then destroys it. If this was the last mbcache, un-registers the -+ * mbcache from kernel memory management. -+ */ -+void -+mb_cache_destroy(struct mb_cache *cache) -+{ -+ LIST_HEAD(free_list); -+ struct list_head *l; -+ int n; -+ -+ spin_lock(&mb_cache_spinlock); -+ l = mb_cache_lru_list.prev; -+ while (l != &mb_cache_lru_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ if (ce->e_cache == cache) { -+ list_move(&ce->e_lru_list, &free_list); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ } -+ } -+ list_del(&cache->c_cache_list); -+ if (list_empty(&mb_cache_list) && mb_shrinker) { -+ remove_shrinker(mb_shrinker); -+ mb_shrinker = 0; -+ } -+ spin_unlock(&mb_cache_spinlock); -+ -+ l = free_list.prev; -+ while (l != &free_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ l = l->prev; -+ __mb_cache_entry_forget(ce); -+ } -+ -+ if (atomic_read(&cache->c_entry_count) > 0) { -+ mb_error("cache %s: %d orphaned entries", -+ cache->c_name, -+ atomic_read(&cache->c_entry_count)); -+ } -+ -+ kmem_cache_destroy(cache->c_entry_cache); -+ -+ for (n=0; n < mb_cache_indexes(cache); n++) -+ kfree(cache->c_indexes_hash[n]); -+ kfree(cache->c_block_hash); -+ -+ kfree(cache); -+} -+ -+ -+/* -+ * mb_cache_entry_alloc() -+ * -+ * Allocates a new cache entry. The new entry will not be valid initially, -+ * and thus cannot be looked up yet. It should be filled with data, and -+ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL -+ * if no more memory was available. -+ */ -+struct mb_cache_entry * -+mb_cache_entry_alloc(struct mb_cache *cache) -+{ -+ struct mb_cache_entry *ce; -+ -+ atomic_inc(&cache->c_entry_count); -+ ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL); -+ if (ce) { -+ INIT_LIST_HEAD(&ce->e_lru_list); -+ INIT_LIST_HEAD(&ce->e_block_list); -+ ce->e_cache = cache; -+ atomic_set(&ce->e_used, 1); -+ } -+ return ce; -+} -+ -+ -+/* -+ * mb_cache_entry_insert() -+ * -+ * Inserts an entry that was allocated using mb_cache_entry_alloc() into -+ * the cache. After this, the cache entry can be looked up, but is not yet -+ * in the lru list as the caller still holds a handle to it. Returns 0 on -+ * success, or -EBUSY if a cache entry for that device + inode exists -+ * already (this may happen after a failed lookup, but when another process -+ * has inserted the same cache entry in the meantime). -+ * -+ * @bdev: device the cache entry belongs to -+ * @block: block number -+ * @keys: array of additional keys. There must be indexes_count entries -+ * in the array (as specified when creating the cache). -+ */ -+int -+mb_cache_entry_insert(struct mb_cache_entry *ce, struct block_device *bdev, -+ sector_t block, unsigned int keys[]) -+{ -+ struct mb_cache *cache = ce->e_cache; -+ unsigned int bucket; -+ struct list_head *l; -+ int error = -EBUSY, n; -+ -+ bucket = hash_long((unsigned long)bdev + (block & 0xffffffff), -+ cache->c_bucket_bits); -+ spin_lock(&mb_cache_spinlock); -+ list_for_each_prev(l, &cache->c_block_hash[bucket]) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_block_list); -+ if (ce->e_bdev == bdev && ce->e_block == block) -+ goto out; -+ } -+ mb_assert(!__mb_cache_entry_is_linked(ce)); -+ ce->e_bdev = bdev; -+ ce->e_block = block; -+ for (n=0; ne_indexes[n].o_key = keys[n]; -+ __mb_cache_entry_link(ce); -+out: -+ spin_unlock(&mb_cache_spinlock); -+ return error; -+} -+ -+ -+/* -+ * mb_cache_entry_release() -+ * -+ * Release a handle to a cache entry. When the last handle to a cache entry -+ * is released it is either freed (if it is invalid) or otherwise inserted -+ * in to the lru list. -+ */ -+void -+mb_cache_entry_release(struct mb_cache_entry *ce) -+{ -+ spin_lock(&mb_cache_spinlock); -+ __mb_cache_entry_release_unlock(ce); -+} -+ -+ -+/* -+ * mb_cache_entry_takeout() -+ * -+ * Take a cache entry out of the cache, making it invalid. The entry can later -+ * be re-inserted using mb_cache_entry_insert(), or released using -+ * mb_cache_entry_release(). -+ */ -+void -+mb_cache_entry_takeout(struct mb_cache_entry *ce) -+{ -+ spin_lock(&mb_cache_spinlock); -+ mb_assert(!__mb_cache_entry_in_lru(ce)); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ spin_unlock(&mb_cache_spinlock); -+} -+ -+ -+/* -+ * mb_cache_entry_free() -+ * -+ * This is equivalent to the sequence mb_cache_entry_takeout() -- -+ * mb_cache_entry_release(). -+ */ -+void -+mb_cache_entry_free(struct mb_cache_entry *ce) -+{ -+ spin_lock(&mb_cache_spinlock); -+ mb_assert(!__mb_cache_entry_in_lru(ce)); -+ if (__mb_cache_entry_is_linked(ce)) -+ __mb_cache_entry_unlink(ce); -+ __mb_cache_entry_release_unlock(ce); -+} -+ -+ -+/* -+ * mb_cache_entry_dup() -+ * -+ * Duplicate a handle to a cache entry (does not duplicate the cache entry -+ * itself). After the call, both the old and the new handle must be released. -+ */ -+struct mb_cache_entry * -+mb_cache_entry_dup(struct mb_cache_entry *ce) -+{ -+ atomic_inc(&ce->e_used); -+ return ce; -+} -+ -+ -+/* -+ * mb_cache_entry_get() -+ * -+ * Get a cache entry by device / block number. (There can only be one entry -+ * in the cache per device and block.) Returns NULL if no such cache entry -+ * exists. -+ */ -+struct mb_cache_entry * -+mb_cache_entry_get(struct mb_cache *cache, struct block_device *bdev, -+ sector_t block) -+{ -+ unsigned int bucket; -+ struct list_head *l; -+ struct mb_cache_entry *ce; -+ -+ bucket = hash_long((unsigned long)bdev + (block & 0xffffffff), -+ cache->c_bucket_bits); -+ spin_lock(&mb_cache_spinlock); -+ list_for_each(l, &cache->c_block_hash[bucket]) { -+ ce = list_entry(l, struct mb_cache_entry, e_block_list); -+ if (ce->e_bdev == bdev && ce->e_block == block) { -+ ce = __mb_cache_entry_read(ce); -+ goto cleanup; -+ } -+ } -+ ce = NULL; -+ -+cleanup: -+ spin_unlock(&mb_cache_spinlock); -+ return ce; -+} -+ -+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) -+ -+static struct mb_cache_entry * -+__mb_cache_entry_find(struct list_head *l, struct list_head *head, -+ int index, struct block_device *bdev, unsigned int key) -+{ -+ while (l != head) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, -+ e_indexes[index].o_list); -+ if (ce->e_bdev == bdev && -+ ce->e_indexes[index].o_key == key) { -+ ce = __mb_cache_entry_read(ce); -+ if (ce) -+ return ce; -+ } -+ l = l->next; -+ } -+ return NULL; -+} -+ -+ -+/* -+ * mb_cache_entry_find_first() -+ * -+ * Find the first cache entry on a given device with a certain key in -+ * an additional index. Additonal matches can be found with -+ * mb_cache_entry_find_next(). Returns NULL if no match was found. -+ * -+ * @cache: the cache to search -+ * @index: the number of the additonal index to search (0<=indexc_bucket_bits); -+ struct list_head *l; -+ struct mb_cache_entry *ce; -+ -+ mb_assert(index < mb_cache_indexes(cache)); -+ spin_lock(&mb_cache_spinlock); -+ l = cache->c_indexes_hash[index][bucket].next; -+ ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket], -+ index, bdev, key); -+ spin_unlock(&mb_cache_spinlock); -+ return ce; -+} -+ -+ -+/* -+ * mb_cache_entry_find_next() -+ * -+ * Find the next cache entry on a given device with a certain key in an -+ * additional index. Returns NULL if no match could be found. The previous -+ * entry is atomatically released, so that mb_cache_entry_find_next() can -+ * be called like this: -+ * -+ * entry = mb_cache_entry_find_first(); -+ * while (entry) { -+ * ... -+ * entry = mb_cache_entry_find_next(entry, ...); -+ * } -+ * -+ * @prev: The previous match -+ * @index: the number of the additonal index to search (0<=indexe_cache; -+ unsigned int bucket = hash_long(key, cache->c_bucket_bits); -+ struct list_head *l; -+ struct mb_cache_entry *ce; -+ -+ mb_assert(index < mb_cache_indexes(cache)); -+ spin_lock(&mb_cache_spinlock); -+ l = prev->e_indexes[index].o_list.next; -+ ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket], -+ index, bdev, key); -+ __mb_cache_entry_release_unlock(prev); -+ return ce; -+} -+ -+#endif /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */ -diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h ---- a/include/linux/ext3_fs.h Sun Dec 8 02:49:56 2002 -+++ b/include/linux/ext3_fs.h Sun Dec 8 02:49:56 2002 -@@ -64,8 +64,6 @@ - */ - #define EXT3_BAD_INO 1 /* Bad blocks inode */ - #define EXT3_ROOT_INO 2 /* Root inode */ --#define EXT3_ACL_IDX_INO 3 /* ACL inode */ --#define EXT3_ACL_DATA_INO 4 /* ACL inode */ - #define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */ - #define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */ - #define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */ -@@ -95,7 +93,6 @@ - #else - # define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) - #endif --#define EXT3_ACLE_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry)) - #define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) - #ifdef __KERNEL__ - # define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) -@@ -130,28 +127,6 @@ - #endif - - /* -- * ACL structures -- */ --struct ext3_acl_header /* Header of Access Control Lists */ --{ -- __u32 aclh_size; -- __u32 aclh_file_count; -- __u32 aclh_acle_count; -- __u32 aclh_first_acle; --}; -- --struct ext3_acl_entry /* Access Control List Entry */ --{ -- __u32 acle_size; -- __u16 acle_perms; /* Access permissions */ -- __u16 acle_type; /* Type of entry */ -- __u16 acle_tag; /* User or group identity */ -- __u16 acle_pad1; -- __u32 acle_next; /* Pointer on next entry for the */ -- /* same inode or on next free entry */ --}; -- --/* - * Structure of a blocks group descriptor - */ - struct ext3_group_desc -@@ -347,6 +322,7 @@ - #define EXT3_MOUNT_WRITEBACK_DATA 0x0C00 /* No data ordering */ - #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ - #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ -+#define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -529,7 +505,7 @@ - #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ - #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ - --#define EXT3_FEATURE_COMPAT_SUPP 0 -+#define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR - #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ - EXT3_FEATURE_INCOMPAT_RECOVER) - #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ -@@ -713,6 +689,7 @@ - - - /* inode.c */ -+extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int); - extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); - extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); - -@@ -781,8 +758,10 @@ - - /* namei.c */ - extern struct inode_operations ext3_dir_inode_operations; -+extern struct inode_operations ext3_special_inode_operations; - - /* symlink.c */ -+extern struct inode_operations ext3_symlink_inode_operations; - extern struct inode_operations ext3_fast_symlink_inode_operations; - - -diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h ---- a/include/linux/ext3_jbd.h Sun Dec 8 02:49:56 2002 -+++ b/include/linux/ext3_jbd.h Sun Dec 8 02:49:56 2002 -@@ -30,13 +30,19 @@ - - #define EXT3_SINGLEDATA_TRANS_BLOCKS 8 - -+/* Extended attributes may touch two data buffers, two bitmap buffers, -+ * and two group and summaries. */ -+ -+#define EXT3_XATTR_TRANS_BLOCKS 8 -+ - /* Define the minimum size for a transaction which modifies data. This - * needs to take into account the fact that we may end up modifying two - * quota files too (one for the group, one for the user quota). The - * superblock only gets updated once, of course, so don't bother - * counting that again for the quota updates. */ - --#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2) -+#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \ -+ EXT3_XATTR_TRANS_BLOCKS - 2) - - extern int ext3_writepage_trans_blocks(struct inode *inode); - -diff -Nru a/include/linux/mbcache.h b/include/linux/mbcache.h ---- /dev/null Wed Dec 31 16:00:00 1969 -+++ b/include/linux/mbcache.h Sun Dec 8 02:49:56 2002 -@@ -0,0 +1,72 @@ -+/* -+ File: linux/mbcache.h -+ -+ (C) 2001 by Andreas Gruenbacher, -+*/ -+ -+/* Hardwire the number of additional indexes */ -+#define MB_CACHE_INDEXES_COUNT 1 -+ -+struct mb_cache_entry; -+ -+struct mb_cache_op { -+ void (*free)(struct mb_cache_entry *); -+}; -+ -+struct mb_cache { -+ struct list_head c_cache_list; -+ const char *c_name; -+ struct mb_cache_op c_op; -+ atomic_t c_entry_count; -+ int c_bucket_bits; -+#ifndef MB_CACHE_INDEXES_COUNT -+ int c_indexes_count; -+#endif -+ kmem_cache_t *c_entry_cache; -+ struct list_head *c_block_hash; -+ struct list_head *c_indexes_hash[0]; -+}; -+ -+struct mb_cache_entry_index { -+ struct list_head o_list; -+ unsigned int o_key; -+}; -+ -+struct mb_cache_entry { -+ struct list_head e_lru_list; -+ struct mb_cache *e_cache; -+ atomic_t e_used; -+ struct block_device *e_bdev; -+ sector_t e_block; -+ struct list_head e_block_list; -+ struct mb_cache_entry_index e_indexes[0]; -+}; -+ -+/* Functions on caches */ -+ -+struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t, -+ int, int); -+void mb_cache_shrink(struct mb_cache *, struct block_device *); -+void mb_cache_destroy(struct mb_cache *); -+ -+/* Functions on cache entries */ -+ -+struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *); -+int mb_cache_entry_insert(struct mb_cache_entry *, struct block_device *, -+ sector_t, unsigned int[]); -+void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]); -+void mb_cache_entry_release(struct mb_cache_entry *); -+void mb_cache_entry_takeout(struct mb_cache_entry *); -+void mb_cache_entry_free(struct mb_cache_entry *); -+struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *); -+struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *, -+ struct block_device *, -+ sector_t); -+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) -+struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int, -+ struct block_device *, -+ unsigned int); -+struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int, -+ struct block_device *, -+ unsigned int); -+#endif diff --git a/lustre/kernel_patches/patches/invalidate_show.patch b/lustre/kernel_patches/patches/invalidate_show.patch deleted file mode 100644 index c3ae2f5..0000000 --- a/lustre/kernel_patches/patches/invalidate_show.patch +++ /dev/null @@ -1,104 +0,0 @@ ---- lum/fs/inode.c Sat Oct 19 11:42:42 2002 -+++ linux-2.4.18-uml35-ext3online/fs/inode.c Mon Oct 14 00:41:20 2002 -@@ -606,7 +553,8 @@ static void dispose_list(struct list_hea - /* - * Invalidate all inodes for a device. - */ --static int invalidate_list(struct list_head *head, struct super_block * sb, struct list_head * dispose) -+static int invalidate_list(struct list_head *head, struct super_block * sb, -+ struct list_head * dispose, int show) - { - struct list_head *next; - int busy = 0, count = 0; -@@ -631,6 +579,11 @@ static int invalidate_list(struct list_h - count++; - continue; - } -+ if (show) -+ printk(KERN_ERR -+ "inode busy: dev %s:%lu (%p) mode %o count %u\n", -+ kdevname(sb->s_dev), inode->i_ino, inode, -+ inode->i_mode, atomic_read(&inode->i_count)); - busy = 1; - } - /* only unused inodes may be cached with i_count zero */ -@@ -649,22 +601,23 @@ static int invalidate_list(struct list_h - /** - * invalidate_inodes - discard the inodes on a device - * @sb: superblock -+ * @show: whether we should display any busy inodes found - * - * Discard all of the inodes for a given superblock. If the discard - * fails because there are busy inodes then a non zero value is returned. - * If the discard is successful all the inodes have been discarded. - */ - --int invalidate_inodes(struct super_block * sb) -+int invalidate_inodes(struct super_block * sb, int show) - { - int busy; - LIST_HEAD(throw_away); - - spin_lock(&inode_lock); -- busy = invalidate_list(&inode_in_use, sb, &throw_away); -- busy |= invalidate_list(&inode_unused, sb, &throw_away); -- busy |= invalidate_list(&sb->s_dirty, sb, &throw_away); -- busy |= invalidate_list(&sb->s_locked_inodes, sb, &throw_away); -+ busy = invalidate_list(&inode_in_use, sb, &throw_away, show); -+ busy |= invalidate_list(&inode_unused, sb, &throw_away, show); -+ busy |= invalidate_list(&sb->s_dirty, sb, &throw_away, show); -+ busy |= invalidate_list(&sb->s_locked_inodes, sb, &throw_away, show); - spin_unlock(&inode_lock); - - dispose_list(&throw_away); -@@ -690,7 +643,7 @@ int invalidate_device(kdev_t dev, int do - * hold). - */ - shrink_dcache_sb(sb); -- res = invalidate_inodes(sb); -+ res = invalidate_inodes(sb, 0); - drop_super(sb); - } - invalidate_buffers(dev); ---- lum/fs/super.c.orig Sat Oct 19 11:42:42 2002 -+++ lum/fs/super.c Wed Oct 30 17:16:55 2002 -@@ -936,7 +936,7 @@ - lock_super(sb); - lock_kernel(); - sb->s_flags &= ~MS_ACTIVE; -- invalidate_inodes(sb); /* bad name - it should be evict_inodes() */ -+ invalidate_inodes(sb, 0); /* bad name - it should be evict_inodes() */ - if (sop) { - if (sop->write_super && sb->s_dirt) - sop->write_super(sb); -@@ -945,7 +945,7 @@ - } - - /* Forget any remaining inodes */ -- if (invalidate_inodes(sb)) { -+ if (invalidate_inodes(sb, 1)) { - printk(KERN_ERR "VFS: Busy inodes after unmount. " - "Self-destruct in 5 seconds. Have a nice day...\n"); - } ---- lum/include/linux/fs.h Wed Oct 30 17:10:42 2002 -+++ lum/include/linux/fs.h.orig Tue Oct 22 23:15:00 2002 -@@ -1261,7 +1261,7 @@ - extern void set_buffer_flushtime(struct buffer_head *); - extern void balance_dirty(void); - extern int check_disk_change(kdev_t); --extern int invalidate_inodes(struct super_block *); -+extern int invalidate_inodes(struct super_block *, int); - extern int invalidate_device(kdev_t, int); - extern void invalidate_inode_pages(struct inode *); - extern void invalidate_inode_pages2(struct address_space *); ---- lum/fs/smbfs/inode.c.orig Mon Feb 25 12:38:09 2002 -+++ lum/fs/smbfs/inode.c Thu Feb 6 21:34:26 2003 -@@ -166,7 +166,7 @@ - { - VERBOSE("\n"); - shrink_dcache_sb(SB_of(server)); -- invalidate_inodes(SB_of(server)); -+ invalidate_inodes(SB_of(server), 0); - } - - /* diff --git a/lustre/kernel_patches/patches/iod-rmap-exports.patch b/lustre/kernel_patches/patches/iod-rmap-exports.patch deleted file mode 100644 index 8df0d82..0000000 --- a/lustre/kernel_patches/patches/iod-rmap-exports.patch +++ /dev/null @@ -1,71 +0,0 @@ ---- linux/fs/inode.c.b_io 2003-02-18 16:39:16.000000000 -0800 -+++ linux/fs/inode.c 2003-02-18 16:39:45.000000000 -0800 -@@ -5,6 +5,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -66,7 +67,8 @@ - * NOTE! You also have to own the lock if you change - * the i_state of an inode while it is in use.. - */ --static spinlock_t inode_lock = SPIN_LOCK_UNLOCKED; -+spinlock_t inode_lock = SPIN_LOCK_UNLOCKED; -+EXPORT_SYMBOL(inode_lock); - - /* - * Statistics gathering.. ---- linux/fs/Makefile.b_io 2003-02-18 16:39:16.000000000 -0800 -+++ linux/fs/Makefile 2003-02-18 16:39:37.000000000 -0800 -@@ -7,7 +7,7 @@ - - O_TARGET := fs.o - --export-objs := filesystems.o open.o dcache.o buffer.o -+export-objs := filesystems.o open.o dcache.o buffer.o inode.o - mod-subdirs := nls - - obj-y := open.o read_write.o devices.o file_table.o buffer.o \ ---- linux/mm/vmscan.c.b_io 2003-02-18 16:39:16.000000000 -0800 -+++ linux/mm/vmscan.c 2003-02-18 16:40:01.000000000 -0800 -@@ -14,6 +14,8 @@ - * Multiqueue VM started 5.8.00, Rik van Riel. - */ - -+#include -+#include - #include - #include - #include -@@ -837,6 +839,7 @@ - set_current_state(TASK_RUNNING); - remove_wait_queue(&kswapd_done, &wait); - } -+EXPORT_SYMBOL(wakeup_kswapd); - - static void wakeup_memwaiters(void) - { ---- linux/mm/Makefile.b_io 2003-02-18 16:39:16.000000000 -0800 -+++ linux/mm/Makefile 2003-02-18 16:39:37.000000000 -0800 -@@ -9,7 +9,7 @@ - - O_TARGET := mm.o - --export-objs := shmem.o filemap.o memory.o page_alloc.o mempool.o -+export-objs := shmem.o filemap.o memory.o page_alloc.o mempool.o vmscan.o - - obj-y := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \ - vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \ ---- linux-chaos/mm/page_alloc.c.b_io_export Wed Jan 29 17:00:32 2003 -+++ linux-chaos/mm/page_alloc.c Wed Jan 29 17:01:31 2003 -@@ -31,6 +31,7 @@ - int nr_inactive_dirty_pages; - int nr_inactive_clean_pages; - pg_data_t *pgdat_list; -+EXPORT_SYMBOL(pgdat_list); - - /* - * The zone_table array is used to look up the address of the diff --git a/lustre/kernel_patches/patches/jbd-transno-cb.patch b/lustre/kernel_patches/patches/jbd-transno-cb.patch deleted file mode 100644 index ceb086d..0000000 --- a/lustre/kernel_patches/patches/jbd-transno-cb.patch +++ /dev/null @@ -1,240 +0,0 @@ - - - - fs/jbd/commit.c | 27 +++++++++++++++++++++--- - fs/jbd/journal.c | 1 - fs/jbd/transaction.c | 56 ++++++++++++++++++++++++++++++++++++++++----------- - include/linux/jbd.h | 20 ++++++++++++++++++ - 4 files changed, 90 insertions(+), 14 deletions(-) - ---- linux-2.4.19/fs/jbd/commit.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/fs/jbd/commit.c Sun Jan 19 19:46:42 2003 -@@ -475,7 +475,7 @@ start_journal_io: - transaction's t_log_list queue, and metadata buffers are on - the t_iobuf_list queue. - -- Wait for the transactions in reverse order. That way we are -+ Wait for the buffers in reverse order. That way we are - less likely to be woken up until all IOs have completed, and - so we incur less scheduling load. - */ -@@ -566,8 +566,10 @@ start_journal_io: - - jbd_debug(3, "JBD: commit phase 6\n"); - -- if (is_journal_aborted(journal)) -+ if (is_journal_aborted(journal)) { -+ unlock_journal(journal); - goto skip_commit; -+ } - - /* Done it all: now write the commit record. We should have - * cleaned up our previous buffers by now, so if we are in abort -@@ -577,6 +579,7 @@ start_journal_io: - descriptor = journal_get_descriptor_buffer(journal); - if (!descriptor) { - __journal_abort_hard(journal); -+ unlock_journal(journal); - goto skip_commit; - } - -@@ -600,7 +603,6 @@ start_journal_io: - put_bh(bh); /* One for getblk() */ - journal_unlock_journal_head(descriptor); - } -- lock_journal(journal); - - /* End of a transaction! Finally, we can do checkpoint - processing: any buffers committed as a result of this -@@ -609,6 +611,25 @@ start_journal_io: - - skip_commit: - -+ /* Call any callbacks that had been registered for handles in this -+ * transaction. It is up to the callback to free any allocated -+ * memory. -+ */ -+ if (!list_empty(&commit_transaction->t_jcb)) { -+ struct list_head *p, *n; -+ int error = is_journal_aborted(journal); -+ -+ list_for_each_safe(p, n, &commit_transaction->t_jcb) { -+ struct journal_callback *jcb; -+ -+ jcb = list_entry(p, struct journal_callback, jcb_list); -+ list_del(p); -+ jcb->jcb_func(jcb, error); -+ } -+ } -+ -+ lock_journal(journal); -+ - jbd_debug(3, "JBD: commit phase 7\n"); - - J_ASSERT(commit_transaction->t_sync_datalist == NULL); ---- linux-2.4.19/fs/jbd/journal.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/fs/jbd/journal.c Sun Jan 19 19:46:42 2003 -@@ -58,6 +58,7 @@ EXPORT_SYMBOL(journal_sync_buffer); - #endif - EXPORT_SYMBOL(journal_flush); - EXPORT_SYMBOL(journal_revoke); -+EXPORT_SYMBOL(journal_callback_set); - - EXPORT_SYMBOL(journal_init_dev); - EXPORT_SYMBOL(journal_init_inode); ---- linux-2.4.19/fs/jbd/transaction.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/fs/jbd/transaction.c Sun Jan 19 19:46:42 2003 -@@ -57,6 +57,7 @@ static transaction_t * get_transaction ( - transaction->t_state = T_RUNNING; - transaction->t_tid = journal->j_transaction_sequence++; - transaction->t_expires = jiffies + journal->j_commit_interval; -+ INIT_LIST_HEAD(&transaction->t_jcb); - - /* Set up the commit timer for the new transaction. */ - J_ASSERT (!journal->j_commit_timer_active); -@@ -201,6 +202,20 @@ repeat_locked: - return 0; - } - -+/* Allocate a new handle. This should probably be in a slab... */ -+static handle_t *new_handle(int nblocks) -+{ -+ handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ if (!handle) -+ return NULL; -+ memset(handle, 0, sizeof (handle_t)); -+ handle->h_buffer_credits = nblocks; -+ handle->h_ref = 1; -+ INIT_LIST_HEAD(&handle->h_jcb); -+ -+ return handle; -+} -+ - /* - * Obtain a new handle. - * -@@ -227,14 +242,11 @@ handle_t *journal_start(journal_t *journ - handle->h_ref++; - return handle; - } -- -- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ -+ handle = new_handle(nblocks); - if (!handle) - return ERR_PTR(-ENOMEM); -- memset (handle, 0, sizeof (handle_t)); - -- handle->h_buffer_credits = nblocks; -- handle->h_ref = 1; - current->journal_info = handle; - - err = start_this_handle(journal, handle); -@@ -333,14 +345,11 @@ handle_t *journal_try_start(journal_t *j - - if (is_journal_aborted(journal)) - return ERR_PTR(-EIO); -- -- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ -+ handle = new_handle(nblocks); - if (!handle) - return ERR_PTR(-ENOMEM); -- memset (handle, 0, sizeof (handle_t)); - -- handle->h_buffer_credits = nblocks; -- handle->h_ref = 1; - current->journal_info = handle; - - err = try_start_this_handle(journal, handle); -@@ -1328,6 +1337,28 @@ out: - #endif - - /* -+ * Register a callback function for this handle. The function will be -+ * called when the transaction that this handle is part of has been -+ * committed to disk with the original callback data struct and the -+ * error status of the journal as parameters. There is no guarantee of -+ * ordering between handles within a single transaction, nor between -+ * callbacks registered on the same handle. -+ * -+ * The caller is responsible for allocating the journal_callback struct. -+ * This is to allow the caller to add as much extra data to the callback -+ * as needed, but reduce the overhead of multiple allocations. The caller -+ * allocated struct must start with a struct journal_callback at offset 0, -+ * and has the caller-specific data afterwards. -+ */ -+void journal_callback_set(handle_t *handle, -+ void (*func)(struct journal_callback *jcb, int error), -+ struct journal_callback *jcb) -+{ -+ list_add(&jcb->jcb_list, &handle->h_jcb); -+ jcb->jcb_func = func; -+} -+ -+/* - * All done for a particular handle. - * - * There is not much action needed here. We just return any remaining -@@ -1393,7 +1424,10 @@ int journal_stop(handle_t *handle) - wake_up(&journal->j_wait_transaction_locked); - } - -- /* -+ /* Move callbacks from the handle to the transaction. */ -+ list_splice(&handle->h_jcb, &transaction->t_jcb); -+ -+ /* - * If the handle is marked SYNC, we need to set another commit - * going! We also want to force a commit if the current - * transaction is occupying too much of the log, or if the ---- linux-2.4.19/include/linux/jbd.h~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/include/linux/jbd.h Sun Jan 19 19:46:42 2003 -@@ -249,6 +249,13 @@ static inline struct journal_head *bh2jh - return bh->b_private; - } - -+#define HAVE_JOURNAL_CALLBACK_STATUS -+struct journal_callback { -+ struct list_head jcb_list; -+ void (*jcb_func)(struct journal_callback *jcb, int error); -+ /* user data goes here */ -+}; -+ - struct jbd_revoke_table_s; - - /* The handle_t type represents a single atomic update being performed -@@ -279,6 +286,12 @@ struct handle_s - operations */ - int h_err; - -+ /* List of application registered callbacks for this handle. -+ * The function(s) will be called after the transaction that -+ * this handle is part of has been committed to disk. -+ */ -+ struct list_head h_jcb; -+ - /* Flags */ - unsigned int h_sync: 1; /* sync-on-close */ - unsigned int h_jdata: 1; /* force data journaling */ -@@ -398,6 +411,10 @@ struct transaction_s - - /* How many handles used this transaction? */ - int t_handle_count; -+ -+ /* List of registered callback functions for this transaction. -+ * Called when the transaction is committed. */ -+ struct list_head t_jcb; - }; - - -@@ -646,6 +663,9 @@ extern int journal_flushpage(journal_t - extern int journal_try_to_free_buffers(journal_t *, struct page *, int); - extern int journal_stop(handle_t *); - extern int journal_flush (journal_t *); -+extern void journal_callback_set(handle_t *handle, -+ void (*fn)(struct journal_callback *,int), -+ struct journal_callback *jcb); - - extern void journal_lock_updates (journal_t *); - extern void journal_unlock_updates (journal_t *); diff --git a/lustre/kernel_patches/patches/kmem_cache_validate.patch b/lustre/kernel_patches/patches/kmem_cache_validate.patch deleted file mode 100644 index 52880d8..0000000 --- a/lustre/kernel_patches/patches/kmem_cache_validate.patch +++ /dev/null @@ -1,119 +0,0 @@ - - - - 0 files changed - ---- linux-2.4.18-17.8.0/arch/i386/mm/init.c~kmem_cache_validate 2002-12-06 14:52:30.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/arch/i386/mm/init.c 2002-12-06 14:52:30.000000000 -0800 -@@ -43,6 +43,12 @@ unsigned long highstart_pfn, highend_pfn - static unsigned long totalram_pages; - static unsigned long totalhigh_pages; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int do_check_pgt_cache(int low, int high) - { - int freed = 0; ---- linux-2.4.18-17.8.0/arch/ia64/mm/init.c~kmem_cache_validate 2002-12-06 14:52:30.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/arch/ia64/mm/init.c 2002-12-06 14:52:30.000000000 -0800 -@@ -37,6 +37,12 @@ unsigned long MAX_DMA_ADDRESS = PAGE_OFF - - static unsigned long totalram_pages; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int - do_check_pgt_cache (int low, int high) - { ---- linux-2.4.18-17.8.0/include/linux/slab.h~kmem_cache_validate 2002-12-06 14:52:30.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/include/linux/slab.h 2002-12-06 14:52:30.000000000 -0800 -@@ -57,6 +57,7 @@ extern int kmem_cache_destroy(kmem_cache - extern int kmem_cache_shrink(kmem_cache_t *); - extern void *kmem_cache_alloc(kmem_cache_t *, int); - extern void kmem_cache_free(kmem_cache_t *, void *); -+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); - - extern void *kmalloc(size_t, int); - extern void kfree(const void *); ---- linux-2.4.18-17.8.0/kernel/ksyms.c~kmem_cache_validate 2002-12-06 14:52:30.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/kernel/ksyms.c 2002-12-06 14:52:30.000000000 -0800 -@@ -119,6 +119,7 @@ EXPORT_SYMBOL(kmem_cache_destroy); - EXPORT_SYMBOL(kmem_cache_shrink); - EXPORT_SYMBOL(kmem_cache_alloc); - EXPORT_SYMBOL(kmem_cache_free); -+EXPORT_SYMBOL(kmem_cache_validate); - EXPORT_SYMBOL(kmalloc); - EXPORT_SYMBOL(kfree); - EXPORT_SYMBOL(vfree); ---- linux-2.4.18-17.8.0/mm/slab.c~kmem_cache_validate 2002-12-06 14:52:30.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/mm/slab.c 2002-12-06 14:52:30.000000000 -0800 -@@ -1208,6 +1208,59 @@ failed: - * Called with the cache-lock held. - */ - -+extern struct page *check_get_page(unsigned long kaddr); -+struct page *page_mem_map(struct page *page); -+static int kmem_check_cache_obj (kmem_cache_t * cachep, -+ slab_t *slabp, void * objp) -+{ -+ int i; -+ unsigned int objnr; -+ -+#if DEBUG -+ if (cachep->flags & SLAB_RED_ZONE) { -+ objp -= BYTES_PER_WORD; -+ if ( *(unsigned long *)objp != RED_MAGIC2) -+ /* Either write before start, or a double free. */ -+ return 0; -+ if (*(unsigned long *)(objp+cachep->objsize - -+ BYTES_PER_WORD) != RED_MAGIC2) -+ /* Either write past end, or a double free. */ -+ return 0; -+ } -+#endif -+ -+ objnr = (objp-slabp->s_mem)/cachep->objsize; -+ if (objnr >= cachep->num) -+ return 0; -+ if (objp != slabp->s_mem + objnr*cachep->objsize) -+ return 0; -+ -+ /* Check slab's freelist to see if this obj is there. */ -+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { -+ if (i == objnr) -+ return 0; -+ } -+ return 1; -+} -+ -+ -+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) -+{ -+ struct page *page = check_get_page((unsigned long)objp); -+ -+ if (!VALID_PAGE(page)) -+ return 0; -+ -+ if (!PageSlab(page)) -+ return 0; -+ -+ /* XXX check for freed slab objects ? */ -+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) -+ return 0; -+ -+ return (cachep == GET_PAGE_CACHE(page)); -+} -+ - #if DEBUG - static int kmem_extra_free_checks (kmem_cache_t * cachep, - slab_t *slabp, void * objp) - -_ diff --git a/lustre/kernel_patches/patches/kmem_cache_validate_hp.patch b/lustre/kernel_patches/patches/kmem_cache_validate_hp.patch deleted file mode 100644 index 03385a7..0000000 --- a/lustre/kernel_patches/patches/kmem_cache_validate_hp.patch +++ /dev/null @@ -1,105 +0,0 @@ - arch/ia64/mm/init.c | 6 +++++ - include/linux/slab.h | 1 - kernel/ksyms.c | 1 - mm/slab.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 61 insertions(+) - ---- linux-2.4.19-hp2_pnnl2/arch/ia64/mm/init.c~kmem_cache_validate_hp Sun Jan 19 18:59:23 2003 -+++ linux-2.4.19-hp2_pnnl2-root/arch/ia64/mm/init.c Sun Jan 19 18:59:24 2003 -@@ -44,6 +44,12 @@ unsigned long vmalloc_end = VMALLOC_END_ - static struct page *vmem_map; - static unsigned long num_dma_physpages; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int - do_check_pgt_cache (int low, int high) - { ---- linux-2.4.19-hp2_pnnl2/include/linux/slab.h~kmem_cache_validate_hp Sun Jan 19 18:59:23 2003 -+++ linux-2.4.19-hp2_pnnl2-root/include/linux/slab.h Sun Jan 19 19:01:07 2003 -@@ -56,6 +56,7 @@ extern kmem_cache_t *kmem_cache_create(c - extern int kmem_cache_destroy(kmem_cache_t *); - extern int kmem_cache_shrink(kmem_cache_t *); - extern void *kmem_cache_alloc(kmem_cache_t *, int); -+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); - extern void kmem_cache_free(kmem_cache_t *, void *); - extern unsigned int kmem_cache_size(kmem_cache_t *); - ---- linux-2.4.19-hp2_pnnl2/kernel/ksyms.c~kmem_cache_validate_hp Sun Jan 19 18:59:23 2003 -+++ linux-2.4.19-hp2_pnnl2-root/kernel/ksyms.c Sun Jan 19 19:00:32 2003 -@@ -118,6 +118,7 @@ EXPORT_SYMBOL(kmem_find_general_cachep); - EXPORT_SYMBOL(kmem_cache_create); - EXPORT_SYMBOL(kmem_cache_destroy); - EXPORT_SYMBOL(kmem_cache_shrink); -+EXPORT_SYMBOL(kmem_cache_validate); - EXPORT_SYMBOL(kmem_cache_alloc); - EXPORT_SYMBOL(kmem_cache_free); - EXPORT_SYMBOL(kmem_cache_size); ---- linux-2.4.19-hp2_pnnl2/mm/slab.c~kmem_cache_validate_hp Sun Jan 19 18:59:23 2003 -+++ linux-2.4.19-hp2_pnnl2-root/mm/slab.c Sun Jan 19 18:59:24 2003 -@@ -1207,6 +1207,59 @@ failed: - * Called with the cache-lock held. - */ - -+extern struct page *check_get_page(unsigned long kaddr); -+struct page *page_mem_map(struct page *page); -+static int kmem_check_cache_obj (kmem_cache_t * cachep, -+ slab_t *slabp, void * objp) -+{ -+ int i; -+ unsigned int objnr; -+ -+#if DEBUG -+ if (cachep->flags & SLAB_RED_ZONE) { -+ objp -= BYTES_PER_WORD; -+ if ( *(unsigned long *)objp != RED_MAGIC2) -+ /* Either write before start, or a double free. */ -+ return 0; -+ if (*(unsigned long *)(objp+cachep->objsize - -+ BYTES_PER_WORD) != RED_MAGIC2) -+ /* Either write past end, or a double free. */ -+ return 0; -+ } -+#endif -+ -+ objnr = (objp-slabp->s_mem)/cachep->objsize; -+ if (objnr >= cachep->num) -+ return 0; -+ if (objp != slabp->s_mem + objnr*cachep->objsize) -+ return 0; -+ -+ /* Check slab's freelist to see if this obj is there. */ -+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { -+ if (i == objnr) -+ return 0; -+ } -+ return 1; -+} -+ -+ -+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) -+{ -+ struct page *page = check_get_page((unsigned long)objp); -+ -+ if (!VALID_PAGE(page)) -+ return 0; -+ -+ if (!PageSlab(page)) -+ return 0; -+ -+ /* XXX check for freed slab objects ? */ -+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) -+ return 0; -+ -+ return (cachep == GET_PAGE_CACHE(page)); -+} -+ - #if DEBUG - static int kmem_extra_free_checks (kmem_cache_t * cachep, - slab_t *slabp, void * objp) - -_ diff --git a/lustre/kernel_patches/patches/lustre-2.5.patch b/lustre/kernel_patches/patches/lustre-2.5.patch deleted file mode 100644 index 71d372f..0000000 --- a/lustre/kernel_patches/patches/lustre-2.5.patch +++ /dev/null @@ -1,507 +0,0 @@ - arch/um/kernel/mem.c | 18 +++++++++++- - fs/namei.c | 71 +++++++++++++++++++++++++++++++++++-------------- - fs/nfsd/vfs.c | 2 - - fs/sysfs/inode.c | 2 - - include/linux/dcache.h | 27 ++++++++++++++++++ - include/linux/fs.h | 20 +++++++++++++ - include/linux/namei.h | 3 +- - include/linux/slab.h | 1 - kernel/ksyms.c | 7 ++++ - mm/slab.c | 5 +++ - net/unix/af_unix.c | 2 - - 11 files changed, 132 insertions(+), 26 deletions(-) - ---- linux-2.5.59/arch/um/kernel/mem.c~lustre-2.5 2003-02-22 21:56:58.000000000 +0800 -+++ linux-2.5.59-root/arch/um/kernel/mem.c 2003-02-22 21:56:58.000000000 +0800 -@@ -639,6 +639,22 @@ struct page *pte_mem_map(pte_t pte) - return(phys_mem_map(pte_val(pte))); - } - -+struct page *check_get_page(unsigned long kaddr) -+{ -+ struct page *page; -+ struct mem_region *mr; -+ unsigned long phys = __pa(kaddr); -+ unsigned int n = phys_region_index(phys); -+ -+ if(regions[n] == NULL) -+ return NULL; -+ -+ mr = regions[n]; -+ page = (struct page *) mr->mem_map; -+ return page + ((phys_addr(phys)) >> PAGE_SHIFT); -+} -+ -+ - struct mem_region *page_region(struct page *page, int *index_out) - { - int i; -@@ -726,7 +742,7 @@ extern unsigned long region_pa(void *vir - (addr <= region->start + region->len)) - return(mk_phys(addr - region->start, i)); - } -- panic("region_pa : no region for virtual address"); -+ //panic("region_pa : no region for virtual address"); - return(0); - } - ---- linux-2.5.59/fs/namei.c~lustre-2.5 2003-02-22 21:56:58.000000000 +0800 -+++ linux-2.5.59-root/fs/namei.c 2003-02-22 21:56:58.000000000 +0800 -@@ -265,6 +265,9 @@ int deny_write_access(struct file * file - - void path_release(struct nameidata *nd) - { -+ if (nd->dentry && nd->dentry->d_op && -+ nd->dentry->d_op->d_intent_release) -+ nd->dentry->d_op->d_intent_release(nd->dentry, &nd->it); - dput(nd->dentry); - mntput(nd->mnt); - } -@@ -273,10 +276,18 @@ void path_release(struct nameidata *nd) - * Internal lookup() using the new generic dcache. - * SMP-safe - */ --static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it) - { - struct dentry * dentry = d_lookup(parent, name); - -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { -+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -351,7 +362,7 @@ ok: - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; -@@ -369,7 +380,10 @@ static struct dentry * real_lookup(struc - struct dentry * dentry = d_alloc(parent, name); - result = ERR_PTR(-ENOMEM); - if (dentry) { -- result = dir->i_op->lookup(dir, dentry); -+ if (dir->i_op->lookup2) -+ result = dir->i_op->lookup2(dir, dentry, it); -+ else -+ result = dir->i_op->lookup(dir, dentry); - if (result) - dput(dentry); - else { -@@ -391,6 +405,12 @@ static struct dentry * real_lookup(struc - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate2) { -+ if (!result->d_op->d_revalidate2(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ result = ERR_PTR(-ENOENT); -+ } - } - return result; - } -@@ -534,7 +554,7 @@ dcache_miss: - unlock_nd(nd); - - need_lookup: -- dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE, &nd->it); - if (IS_ERR(dentry)) - goto fail; - mntget(mnt); -@@ -684,7 +704,7 @@ int link_path_walk(const char * name, st - nd->dentry = next.dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup2) - break; - continue; - /* here ends the main loop */ -@@ -737,7 +757,8 @@ last_component: - break; - if (lookup_flags & LOOKUP_DIRECTORY) { - err = -ENOTDIR; -- if (!inode->i_op || !inode->i_op->lookup) -+ if (!inode->i_op || -+ (!inode->i_op->lookup && !inode->i_op->lookup2)) - break; - } - goto return_base; -@@ -886,7 +907,8 @@ int path_lookup(const char *name, unsign - * needs parent already locked. Doesn't follow mounts. - * SMP-safe. - */ --struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+struct dentry * lookup_hash(struct qstr *name, struct dentry * base, -+ struct lookup_intent *it) - { - struct dentry * dentry; - struct inode *inode; -@@ -909,13 +931,16 @@ struct dentry * lookup_hash(struct qstr - goto out; - } - -- dentry = cached_lookup(base, name, 0); -+ dentry = cached_lookup(base, name, 0, it); - if (!dentry) { - struct dentry *new = d_alloc(base, name); - dentry = ERR_PTR(-ENOMEM); - if (!new) - goto out; -- dentry = inode->i_op->lookup(inode, new); -+ if (inode->i_op->lookup2) -+ dentry = inode->i_op->lookup2(inode, new, it); -+ else -+ dentry = inode->i_op->lookup(inode, new); - if (!dentry) { - dentry = new; - security_inode_post_lookup(inode, dentry); -@@ -927,7 +952,7 @@ out: - } - - /* SMP-safe */ --struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -+struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct lookup_intent *it) - { - unsigned long hash; - struct qstr this; -@@ -947,11 +972,16 @@ struct dentry * lookup_one_len(const cha - } - this.hash = end_name_hash(hash); - -- return lookup_hash(&this, base); -+ return lookup_hash(&this, base, it); - access: - return ERR_PTR(-EACCES); - } - -+struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -+{ -+ return lookup_one_len_it(name, base, len, NULL); -+} -+ - /* - * namei() - * -@@ -1268,7 +1298,7 @@ int open_namei(const char * pathname, in - - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash(&nd->last, nd->dentry, &nd->it); - - do_last: - error = PTR_ERR(dentry); -@@ -1371,7 +1401,7 @@ do_link: - } - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash(&nd->last, nd->dentry, &nd->it); - putname(nd->last.name); - goto do_last; - } -@@ -1385,7 +1415,7 @@ static struct dentry *lookup_create(stru - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash(&nd->last, nd->dentry, &nd->it); - if (IS_ERR(dentry)) - goto fail; - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) -@@ -1617,7 +1647,7 @@ asmlinkage long sys_rmdir(const char * p - goto exit1; - } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, &nd.it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); -@@ -1677,7 +1707,7 @@ asmlinkage long sys_unlink(const char * - if (nd.last_type != LAST_NORM) - goto exit1; - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, &nd.it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - /* Why not before? Because we want correct error value */ -@@ -1951,7 +1981,8 @@ int vfs_rename_other(struct inode *old_d - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); -@@ -2022,7 +2053,7 @@ static inline int do_rename(const char * - - trap = lock_rename(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash(&oldnd.last, old_dir, &oldnd.it); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -2042,7 +2073,7 @@ static inline int do_rename(const char * - error = -EINVAL; - if (old_dentry == trap) - goto exit4; -- new_dentry = lookup_hash(&newnd.last, new_dir); -+ new_dentry = lookup_hash(&newnd.last, new_dir, &newnd.it); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; -@@ -2052,7 +2083,7 @@ static inline int do_rename(const char * - goto exit5; - - error = vfs_rename(old_dir->d_inode, old_dentry, -- new_dir->d_inode, new_dentry); -+ new_dir->d_inode, new_dentry, NULL); - exit5: - dput(new_dentry); - exit4: ---- linux-2.5.59/fs/nfsd/vfs.c~lustre-2.5 2003-02-22 21:56:58.000000000 +0800 -+++ linux-2.5.59-root/fs/nfsd/vfs.c 2003-02-22 21:56:58.000000000 +0800 -@@ -1337,7 +1337,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); - nfsd_sync_dir(fdentry); ---- linux-2.5.59/fs/sysfs/inode.c~lustre-2.5 2003-02-22 21:56:58.000000000 +0800 -+++ linux-2.5.59-root/fs/sysfs/inode.c 2003-02-22 21:56:58.000000000 +0800 -@@ -539,7 +539,7 @@ static struct dentry * get_dentry(struct - qstr.name = name; - qstr.len = strlen(name); - qstr.hash = full_name_hash(name,qstr.len); -- return lookup_hash(&qstr,parent); -+ return lookup_hash(&qstr,parent,NULL); - } - - ---- linux-2.5.59/include/linux/dcache.h~lustre-2.5 2003-02-22 21:56:58.000000000 +0800 -+++ linux-2.5.59-root/include/linux/dcache.h 2003-02-22 22:02:55.000000000 +0800 -@@ -11,6 +11,27 @@ - - struct vfsmount; - -+#define IT_OPEN (1) -+#define IT_CREAT (1<<1) -+#define IT_READDIR (1<<2) -+#define IT_GETATTR (1<<3) -+#define IT_LOOKUP (1<<4) -+#define IT_UNLINK (1<<5) -+ -+ -+struct lookup_intent { -+ int it_op; -+ int it_mode; -+ int it_flags; -+ int it_disposition; -+ int it_status; -+ struct iattr *it_iattr; -+ __u64 it_lock_handle[2]; -+ int it_lock_mode; -+ void *it_data; -+}; -+ -+ - /* - * linux/include/linux/dcache.h - * -@@ -32,6 +53,8 @@ struct qstr { - unsigned int hash; - }; - -+#include -+ - struct dentry_stat_t { - int nr_dentry; - int nr_unused; -@@ -81,6 +104,7 @@ struct dentry { - struct list_head d_subdirs; /* our children */ - struct list_head d_alias; /* inode alias list */ - int d_mounted; -+ struct lookup_intent *d_it; - struct qstr d_name; - unsigned long d_time; /* used by d_revalidate */ - struct dentry_operations *d_op; -@@ -100,6 +124,8 @@ struct dentry_operations { - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); -+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); - }; - - /* the dentry parameter passed to d_hash and d_compare is the parent -@@ -139,6 +165,7 @@ d_iput: no no yes - */ - - #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */ -+#define DCACHE_LUSTRE_INVALID 0x0010 /* Lustre invalidated */ - - extern spinlock_t dcache_lock; - extern rwlock_t dparent_lock; ---- linux-2.5.59/include/linux/fs.h~lustre-2.5 2003-02-22 21:56:58.000000000 +0800 -+++ linux-2.5.59-root/include/linux/fs.h 2003-02-22 22:52:58.000000000 +0800 -@@ -234,6 +234,9 @@ typedef int (get_blocks_t)(struct inode - #define ATTR_ATTR_FLAG 1024 - #define ATTR_KILL_SUID 2048 - #define ATTR_KILL_SGID 4096 -+#define ATTR_RAW 8192 /* file system, not vfs will massage attrs */ -+#define ATTR_FROM_OPEN 16384 /* called from open path, ie O_TRUNC */ -+ - - /* - * This is the Inode Attributes structure, used for notify_change(). It -@@ -676,7 +679,7 @@ extern int vfs_symlink(struct inode *, s - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct lookup_intent *it); - - /* - * File types -@@ -762,19 +765,33 @@ struct file_operations { - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup2) (struct inode *,struct dentry *, -+ struct lookup_intent *); - int (*link) (struct dentry *,struct inode *,struct dentry *); -+ int (*link2) (struct inode *,struct inode *, const char *, int); - int (*unlink) (struct inode *,struct dentry *); -+ int (*unlink2) (struct inode *, const char *, int); - int (*symlink) (struct inode *,struct dentry *,const char *); -+ int (*symlink2) (struct inode *, const char *, int, const char *); - int (*mkdir) (struct inode *,struct dentry *,int); -+ int (*mkdir2) (struct inode *, const char *, int,int); - int (*rmdir) (struct inode *,struct dentry *); -+ int (*rmdir2) (struct inode *, const char *, int); - int (*mknod) (struct inode *,struct dentry *,int,dev_t); -+ int (*mknod2) (struct inode *, const char *, int,int,int); - int (*rename) (struct inode *, struct dentry *, - struct inode *, struct dentry *); -+ int (*rename2) (struct inode *, struct inode *, -+ const char *oldname, int oldlen, -+ const char *newname, int newlen); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); -+ int (*follow_link2) (struct dentry *, struct nameidata *, -+ struct lookup_intent *it); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*setattr) (struct dentry *, struct iattr *); -+ int (*setattr_raw) (struct inode *, struct iattr *); - int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); - int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); - ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); -@@ -987,6 +1004,7 @@ extern int register_filesystem(struct fi - extern int unregister_filesystem(struct file_system_type *); - extern struct vfsmount *kern_mount(struct file_system_type *); - extern int may_umount(struct vfsmount *); -+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); - extern long do_mount(char *, char *, char *, unsigned long, void *); - - extern int vfs_statfs(struct super_block *, struct statfs *); ---- linux-2.5.59/include/linux/namei.h~lustre-2.5 2003-02-22 21:56:58.000000000 +0800 -+++ linux-2.5.59-root/include/linux/namei.h 2003-02-22 21:56:58.000000000 +0800 -@@ -13,6 +13,7 @@ struct nameidata { - int last_type; - struct dentry *old_dentry; - struct vfsmount *old_mnt; -+ struct lookup_intent it; - }; - - /* -@@ -46,7 +47,7 @@ extern int FASTCALL(link_path_walk(const - extern void path_release(struct nameidata *); - - extern struct dentry * lookup_one_len(const char *, struct dentry *, int); --extern struct dentry * lookup_hash(struct qstr *, struct dentry *); -+extern struct dentry * lookup_hash(struct qstr *, struct dentry *, struct lookup_intent *); - - extern int follow_down(struct vfsmount **, struct dentry **); - extern int follow_up(struct vfsmount **, struct dentry **); ---- linux-2.5.59/include/linux/slab.h~lustre-2.5 2003-02-22 21:56:58.000000000 +0800 -+++ linux-2.5.59-root/include/linux/slab.h 2003-02-22 21:56:58.000000000 +0800 -@@ -56,6 +56,7 @@ extern int kmem_cache_destroy(kmem_cache - extern int kmem_cache_shrink(kmem_cache_t *); - extern void *kmem_cache_alloc(kmem_cache_t *, int); - extern void kmem_cache_free(kmem_cache_t *, void *); -+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); - extern unsigned int kmem_cache_size(kmem_cache_t *); - - extern void *kmalloc(size_t, int); ---- linux-2.5.59/kernel/ksyms.c~lustre-2.5 2003-02-22 21:56:58.000000000 +0800 -+++ linux-2.5.59-root/kernel/ksyms.c 2003-02-22 21:56:58.000000000 +0800 -@@ -376,6 +376,7 @@ EXPORT_SYMBOL(unregister_filesystem); - EXPORT_SYMBOL(kern_mount); - EXPORT_SYMBOL(__mntput); - EXPORT_SYMBOL(may_umount); -+EXPORT_SYMBOL(reparent_to_init); - - /* executable format registration */ - EXPORT_SYMBOL(register_binfmt); -@@ -406,6 +407,12 @@ EXPORT_SYMBOL(request_irq); - EXPORT_SYMBOL(free_irq); - EXPORT_SYMBOL(irq_stat); - -+/* lustre */ -+EXPORT_SYMBOL(do_kern_mount); -+EXPORT_SYMBOL(exit_files); -+EXPORT_SYMBOL(kmem_cache_validate); -+ -+ - /* waitqueue handling */ - EXPORT_SYMBOL(add_wait_queue); - EXPORT_SYMBOL(add_wait_queue_exclusive); ---- linux-2.5.59/mm/slab.c~lustre-2.5 2003-02-22 21:56:58.000000000 +0800 -+++ linux-2.5.59-root/mm/slab.c 2003-02-22 21:56:58.000000000 +0800 -@@ -1793,6 +1793,11 @@ static inline void __cache_free (kmem_ca - } - } - -+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) -+{ -+ return 1; -+} -+ - /** - * kmem_cache_alloc - Allocate an object - * @cachep: The cache to allocate from. ---- linux-2.5.59/net/unix/af_unix.c~lustre-2.5 2003-02-22 21:56:58.000000000 +0800 -+++ linux-2.5.59-root/net/unix/af_unix.c 2003-02-22 21:56:58.000000000 +0800 -@@ -719,7 +719,7 @@ static int unix_bind(struct socket *sock - /* - * Do the final lookup. - */ -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - goto out_mknod_unlock; - -_ diff --git a/lustre/kernel_patches/patches/lustre_version.patch b/lustre/kernel_patches/patches/lustre_version.patch deleted file mode 100644 index d7b6dce..0000000 --- a/lustre/kernel_patches/patches/lustre_version.patch +++ /dev/null @@ -1,12 +0,0 @@ - - - - include/linux/lustre_version.h | 1 + - 1 files changed, 1 insertion(+) - ---- /dev/null Fri Aug 30 17:31:37 2002 -+++ linux-2.4.18-18.8.0-l12-braam/include/linux/lustre_version.h Thu Feb 13 07:58:33 2003 -@@ -0,0 +1 @@ -+#define LUSTRE_KERNEL_VERSION 13 - -_ diff --git a/lustre/kernel_patches/patches/patch-2.4.18-hp1_pnnl18.2.8qsnet.patch b/lustre/kernel_patches/patches/patch-2.4.18-hp1_pnnl18.2.8qsnet.patch deleted file mode 100644 index f25baa4..0000000 --- a/lustre/kernel_patches/patches/patch-2.4.18-hp1_pnnl18.2.8qsnet.patch +++ /dev/null @@ -1,1673 +0,0 @@ ---- linux-pristine/./include/linux/lustre_version.h Wed Dec 31 19:00:00 1969 -+++ linux/./include/linux/lustre_version.h Tue Nov 26 07:02:14 2002 -@@ -0,0 +1 @@ -+#define LUSTRE_KERNEL_VERSION 5 ---- linux-pristine/./arch/ia64/mm/init.c Thu Dec 5 10:47:25 2002 -+++ linux/./arch/ia64/mm/init.c Fri Nov 29 18:06:20 2002 -@@ -44,6 +44,12 @@ - - static struct page *vmem_map; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int - do_check_pgt_cache (int low, int high) - { ---- linux-pristine/./arch/i386/mm/init.c Thu Dec 5 10:47:24 2002 -+++ linux/./arch/i386/mm/init.c Fri Nov 29 18:06:20 2002 -@@ -43,6 +43,12 @@ - static unsigned long totalram_pages; - static unsigned long totalhigh_pages; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int do_check_pgt_cache(int low, int high) - { - int freed = 0; ---- linux-pristine/./drivers/block/blkpg.c Thu Dec 5 10:47:36 2002 -+++ linux/./drivers/block/blkpg.c Fri Nov 29 18:08:05 2002 -@@ -308,6 +308,41 @@ - - EXPORT_SYMBOL(blk_ioctl); - -+#define NUM_DEV_NO_WRITE 16 -+static int dev_no_write[NUM_DEV_NO_WRITE]; -+ -+/* -+ * Debug code for turning block devices "read-only" (will discard writes -+ * silently). This is for filesystem crash/recovery testing. -+ */ -+void dev_set_rdonly(kdev_t dev, int no_write) -+{ -+ if (dev) { -+ printk(KERN_WARNING "Turning device %s read-only\n", -+ bdevname(dev)); -+ dev_no_write[no_write] = 0xdead0000 + dev; -+ } -+} -+ -+int dev_check_rdonly(kdev_t dev) { -+ int i; -+ -+ for (i = 0; i < NUM_DEV_NO_WRITE; i++) { -+ if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 && -+ dev == (dev_no_write[i] & 0xffff)) -+ return 1; -+ } -+ return 0; -+} -+ -+void dev_clear_rdonly(int no_write) { -+ dev_no_write[no_write] = 0; -+} -+ -+EXPORT_SYMBOL(dev_set_rdonly); -+EXPORT_SYMBOL(dev_check_rdonly); -+EXPORT_SYMBOL(dev_clear_rdonly); -+ - /********************* - * get_last_sector() - * ---- linux-pristine/./drivers/block/loop.c Thu Dec 5 10:47:37 2002 -+++ linux/./drivers/block/loop.c Fri Nov 29 18:06:20 2002 -@@ -471,6 +471,11 @@ - spin_unlock_irq(&lo->lo_lock); - - if (rw == WRITE) { -+#ifdef CONFIG_DEV_RDONLY -+ if (dev_check_rdonly(rbh->b_rdev)) -+ goto err; -+#endif -+ - if (lo->lo_flags & LO_FLAGS_READ_ONLY) - goto err; - } else if (rw == READA) { ---- linux-pristine/./drivers/ide/ide-disk.c Thu Dec 5 10:47:59 2002 -+++ linux/./drivers/ide/ide-disk.c Fri Nov 29 18:06:20 2002 -@@ -367,6 +367,12 @@ - */ - static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) - { -+#ifdef CONFIG_DEV_RDONLY -+ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { -+ ide_end_request(1, HWGROUP(drive)); -+ return ide_stopped; -+ } -+#endif - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl,IDE_CONTROL_REG); - OUT_BYTE(0x00, IDE_FEATURE_REG); ---- linux-pristine/./fs/ext3/Makefile Thu Dec 5 10:49:13 2002 -+++ linux/./fs/ext3/Makefile Fri Nov 29 18:06:20 2002 -@@ -9,6 +9,8 @@ - - O_TARGET := ext3.o - -+export-objs := super.o -+ - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o - obj-m := $(O_TARGET) ---- linux-pristine/./fs/ext3/super.c Thu Dec 5 10:49:13 2002 -+++ linux/./fs/ext3/super.c Fri Nov 29 18:06:20 2002 -@@ -1744,7 +1744,7 @@ - unregister_filesystem(&ext3_fs_type); - } - --EXPORT_NO_SYMBOLS; -+EXPORT_SYMBOL(ext3_bread); - - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); - MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); ---- linux-pristine/./fs/jbd/commit.c Thu Dec 5 10:49:15 2002 -+++ linux/./fs/jbd/commit.c Fri Nov 29 18:06:20 2002 -@@ -475,7 +475,7 @@ - transaction's t_log_list queue, and metadata buffers are on - the t_iobuf_list queue. - -- Wait for the transactions in reverse order. That way we are -+ Wait for the buffers in reverse order. That way we are - less likely to be woken up until all IOs have completed, and - so we incur less scheduling load. - */ -@@ -566,8 +566,10 @@ - - jbd_debug(3, "JBD: commit phase 6\n"); - -- if (is_journal_aborted(journal)) -+ if (is_journal_aborted(journal)) { -+ unlock_journal(journal); - goto skip_commit; -+ } - - /* Done it all: now write the commit record. We should have - * cleaned up our previous buffers by now, so if we are in abort -@@ -577,6 +579,7 @@ - descriptor = journal_get_descriptor_buffer(journal); - if (!descriptor) { - __journal_abort_hard(journal); -+ unlock_journal(journal); - goto skip_commit; - } - -@@ -600,7 +603,6 @@ - put_bh(bh); /* One for getblk() */ - journal_unlock_journal_head(descriptor); - } -- lock_journal(journal); - - /* End of a transaction! Finally, we can do checkpoint - processing: any buffers committed as a result of this -@@ -609,6 +611,25 @@ - - skip_commit: - -+ /* Call any callbacks that had been registered for handles in this -+ * transaction. It is up to the callback to free any allocated -+ * memory. -+ */ -+ if (!list_empty(&commit_transaction->t_jcb)) { -+ struct list_head *p, *n; -+ int error = is_journal_aborted(journal); -+ -+ list_for_each_safe(p, n, &commit_transaction->t_jcb) { -+ struct journal_callback *jcb; -+ -+ jcb = list_entry(p, struct journal_callback, jcb_list); -+ list_del(p); -+ jcb->jcb_func(jcb, error); -+ } -+ } -+ -+ lock_journal(journal); -+ - jbd_debug(3, "JBD: commit phase 7\n"); - - J_ASSERT(commit_transaction->t_sync_datalist == NULL); ---- linux-pristine/./fs/jbd/journal.c Thu Dec 5 10:49:15 2002 -+++ linux/./fs/jbd/journal.c Fri Nov 29 18:06:20 2002 -@@ -58,6 +58,7 @@ - #endif - EXPORT_SYMBOL(journal_flush); - EXPORT_SYMBOL(journal_revoke); -+EXPORT_SYMBOL(journal_callback_set); - - EXPORT_SYMBOL(journal_init_dev); - EXPORT_SYMBOL(journal_init_inode); ---- linux-pristine/./fs/jbd/transaction.c Thu Dec 5 10:49:15 2002 -+++ linux/./fs/jbd/transaction.c Fri Nov 29 18:06:20 2002 -@@ -57,6 +57,7 @@ - transaction->t_state = T_RUNNING; - transaction->t_tid = journal->j_transaction_sequence++; - transaction->t_expires = jiffies + journal->j_commit_interval; -+ INIT_LIST_HEAD(&transaction->t_jcb); - - /* Set up the commit timer for the new transaction. */ - J_ASSERT (!journal->j_commit_timer_active); -@@ -201,6 +202,20 @@ - return 0; - } - -+/* Allocate a new handle. This should probably be in a slab... */ -+static handle_t *new_handle(int nblocks) -+{ -+ handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ if (!handle) -+ return NULL; -+ memset(handle, 0, sizeof (handle_t)); -+ handle->h_buffer_credits = nblocks; -+ handle->h_ref = 1; -+ INIT_LIST_HEAD(&handle->h_jcb); -+ -+ return handle; -+} -+ - /* - * Obtain a new handle. - * -@@ -227,14 +242,11 @@ - handle->h_ref++; - return handle; - } -- -- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ -+ handle = new_handle(nblocks); - if (!handle) - return ERR_PTR(-ENOMEM); -- memset (handle, 0, sizeof (handle_t)); - -- handle->h_buffer_credits = nblocks; -- handle->h_ref = 1; - current->journal_info = handle; - - err = start_this_handle(journal, handle); -@@ -333,14 +345,11 @@ - - if (is_journal_aborted(journal)) - return ERR_PTR(-EIO); -- -- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); -+ -+ handle = new_handle(nblocks); - if (!handle) - return ERR_PTR(-ENOMEM); -- memset (handle, 0, sizeof (handle_t)); - -- handle->h_buffer_credits = nblocks; -- handle->h_ref = 1; - current->journal_info = handle; - - err = try_start_this_handle(journal, handle); -@@ -1328,6 +1337,28 @@ - #endif - - /* -+ * Register a callback function for this handle. The function will be -+ * called when the transaction that this handle is part of has been -+ * committed to disk with the original callback data struct and the -+ * error status of the journal as parameters. There is no guarantee of -+ * ordering between handles within a single transaction, nor between -+ * callbacks registered on the same handle. -+ * -+ * The caller is responsible for allocating the journal_callback struct. -+ * This is to allow the caller to add as much extra data to the callback -+ * as needed, but reduce the overhead of multiple allocations. The caller -+ * allocated struct must start with a struct journal_callback at offset 0, -+ * and has the caller-specific data afterwards. -+ */ -+void journal_callback_set(handle_t *handle, -+ void (*func)(struct journal_callback *jcb, int error), -+ struct journal_callback *jcb) -+{ -+ list_add(&jcb->jcb_list, &handle->h_jcb); -+ jcb->jcb_func = func; -+} -+ -+/* - * All done for a particular handle. - * - * There is not much action needed here. We just return any remaining -@@ -1393,7 +1424,10 @@ - wake_up(&journal->j_wait_transaction_locked); - } - -- /* -+ /* Move callbacks from the handle to the transaction. */ -+ list_splice(&handle->h_jcb, &transaction->t_jcb); -+ -+ /* - * If the handle is marked SYNC, we need to set another commit - * going! We also want to force a commit if the current - * transaction is occupying too much of the log, or if the ---- linux-pristine/./include/linux/blkdev.h Thu Dec 5 10:49:41 2002 -+++ linux/./include/linux/blkdev.h Fri Nov 29 18:30:34 2002 -@@ -228,4 +228,8 @@ - return retval; - } - -+#define CONFIG_DEV_RDONLY -+void dev_set_rdonly(kdev_t, int); -+int dev_check_rdonly(kdev_t); -+void dev_clear_rdonly(int); - #endif ---- linux-pristine/./include/linux/slab.h Thu Dec 5 10:49:53 2002 -+++ linux/./include/linux/slab.h Fri Nov 29 18:30:15 2002 -@@ -58,6 +58,7 @@ - extern void *kmem_cache_alloc(kmem_cache_t *, int); - extern void *kmem_cache_zalloc(kmem_cache_t *, int); - extern void kmem_cache_free(kmem_cache_t *, void *); -+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); - - extern void *kmalloc(size_t, int); - extern void kfree(const void *); ---- linux-pristine/./include/linux/jbd.h Thu Dec 5 10:49:43 2002 -+++ linux/./include/linux/jbd.h Fri Nov 29 18:50:01 2002 -@@ -249,6 +249,13 @@ - return bh->b_private; - } - -+#define HAVE_JOURNAL_CALLBACK_STATUS -+struct journal_callback { -+ struct list_head jcb_list; -+ void (*jcb_func)(struct journal_callback *jcb, int error); -+ /* user data goes here */ -+}; -+ - struct jbd_revoke_table_s; - - /* The handle_t type represents a single atomic update being performed -@@ -279,6 +286,12 @@ - operations */ - int h_err; - -+ /* List of application registered callbacks for this handle. -+ * The function(s) will be called after the transaction that -+ * this handle is part of has been committed to disk. -+ */ -+ struct list_head h_jcb; -+ - /* Flags */ - unsigned int h_sync: 1; /* sync-on-close */ - unsigned int h_jdata: 1; /* force data journaling */ -@@ -398,6 +411,10 @@ - - /* How many handles used this transaction? */ - int t_handle_count; -+ -+ /* List of registered callback functions for this transaction. -+ * Called when the transaction is committed. */ -+ struct list_head t_jcb; - }; - - -@@ -646,6 +663,9 @@ - extern int journal_try_to_free_buffers(journal_t *, struct page *, int); - extern int journal_stop(handle_t *); - extern int journal_flush (journal_t *); -+extern void journal_callback_set(handle_t *handle, -+ void (*fn)(struct journal_callback *,int), -+ struct journal_callback *jcb); - - extern void journal_lock_updates (journal_t *); - extern void journal_unlock_updates (journal_t *); ---- linux-pristine/./kernel/ksyms.c Thu Dec 5 10:50:01 2002 -+++ linux/./kernel/ksyms.c Fri Nov 29 18:37:23 2002 -@@ -271,6 +271,7 @@ - EXPORT_SYMBOL(set_page_dirty); - EXPORT_SYMBOL(vfs_readlink); - EXPORT_SYMBOL(vfs_follow_link); -+EXPORT_SYMBOL(vfs_follow_link_it); - EXPORT_SYMBOL(page_readlink); - EXPORT_SYMBOL(page_follow_link); - EXPORT_SYMBOL(page_symlink_inode_operations); -@@ -285,6 +286,11 @@ - EXPORT_SYMBOL(nr_free_pages); - EXPORT_SYMBOL(page_cache_size); - -+/* lustre */ -+EXPORT_SYMBOL(pagecache_lock); -+EXPORT_SYMBOL(do_kern_mount); -+EXPORT_SYMBOL(kmem_cache_validate); -+ - /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ - EXPORT_SYMBOL(default_llseek); - EXPORT_SYMBOL(dentry_open); ---- linux-pristine/./include/linux/dcache.h Thu Dec 5 10:49:42 2002 -+++ linux/./include/linux/dcache.h Fri Nov 29 18:30:11 2002 -@@ -6,6 +6,34 @@ - #include - #include - -+#define IT_OPEN (1) -+#define IT_CREAT (1<<1) -+#define IT_MKDIR (1<<2) -+#define IT_LINK (1<<3) -+#define IT_LINK2 (1<<4) -+#define IT_SYMLINK (1<<5) -+#define IT_UNLINK (1<<6) -+#define IT_RMDIR (1<<7) -+#define IT_RENAME (1<<8) -+#define IT_RENAME2 (1<<9) -+#define IT_READDIR (1<<10) -+#define IT_GETATTR (1<<11) -+#define IT_SETATTR (1<<12) -+#define IT_READLINK (1<<13) -+#define IT_MKNOD (1<<14) -+#define IT_LOOKUP (1<<15) -+ -+struct lookup_intent { -+ int it_op; -+ int it_mode; -+ int it_disposition; -+ int it_status; -+ struct iattr *it_iattr; -+ __u64 it_lock_handle[2]; -+ int it_lock_mode; -+ void *it_data; -+}; -+ - /* - * linux/include/linux/dcache.h - * -@@ -78,6 +106,7 @@ - unsigned long d_time; /* used by d_revalidate */ - struct dentry_operations *d_op; - struct super_block * d_sb; /* The root of the dentry tree */ -+ struct lookup_intent *d_it; - unsigned long d_vfs_flags; - void * d_fsdata; /* fs-specific data */ - unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */ -@@ -90,6 +119,8 @@ - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); -+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); - }; - - /* the dentry parameter passed to d_hash and d_compare is the parent ---- linux-pristine/./include/linux/fs.h Thu Dec 5 10:49:42 2002 -+++ linux/./include/linux/fs.h Fri Nov 29 18:30:15 2002 -@@ -588,6 +588,7 @@ - - /* needed for tty driver, and maybe others */ - void *private_data; -+ struct lookup_intent *f_intent; - - /* preallocated helper kiobuf to speedup O_DIRECT */ - struct kiobuf *f_iobuf; -@@ -849,7 +850,9 @@ - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it); - - /* - * File types -@@ -911,6 +914,7 @@ - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *); - int (*link) (struct dentry *,struct inode *,struct dentry *); - int (*unlink) (struct inode *,struct dentry *); - int (*symlink) (struct inode *,struct dentry *,const char *); -@@ -921,6 +925,8 @@ - struct inode *, struct dentry *); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); -+ int (*follow_link2) (struct dentry *, struct nameidata *, -+ struct lookup_intent *it); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*revalidate) (struct dentry *); -@@ -1063,7 +1069,7 @@ - extern struct vfsmount *kern_mount(struct file_system_type *); - extern int may_umount(struct vfsmount *); - extern long do_mount(char *, char *, char *, unsigned long, void *); -- -+struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data); - #define kern_umount mntput - - extern int vfs_statfs(struct super_block *, struct statfs *); -@@ -1387,6 +1393,7 @@ - extern loff_t default_llseek(struct file *file, loff_t offset, int origin); - - extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *)); -+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it)); - extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *)); - extern int FASTCALL(path_walk(const char *, struct nameidata *)); - extern int FASTCALL(link_path_walk(const char *, struct nameidata *)); -@@ -1397,6 +1404,8 @@ - extern struct dentry * lookup_hash(struct qstr *, struct dentry *); - #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) - #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) -+#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it) -+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it) - - extern void iput(struct inode *); - extern void force_delete(struct inode *); -@@ -1508,6 +1517,8 @@ - - extern int vfs_readlink(struct dentry *, char *, int, const char *); - extern int vfs_follow_link(struct nameidata *, const char *); -+extern int vfs_follow_link_it(struct nameidata *, const char *, -+ struct lookup_intent *it); - extern int page_readlink(struct dentry *, char *, int); - extern int page_follow_link(struct dentry *, struct nameidata *); - extern struct inode_operations page_symlink_inode_operations; ---- linux-pristine/./fs/dcache.c Thu Dec 5 10:49:13 2002 -+++ linux/./fs/dcache.c Fri Nov 29 18:06:20 2002 -@@ -617,6 +617,7 @@ - dentry->d_op = NULL; - dentry->d_fsdata = NULL; - dentry->d_mounted = 0; -+ dentry->d_it = NULL; - INIT_LIST_HEAD(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); ---- linux-pristine/./fs/nfsd/vfs.c Thu Dec 5 10:49:18 2002 -+++ linux/./fs/nfsd/vfs.c Fri Nov 29 18:06:20 2002 -@@ -1285,7 +1285,7 @@ - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); - nfsd_sync_dir(fdentry); ---- linux-pristine/./fs/namei.c Thu Dec 5 10:49:16 2002 -+++ linux/./fs/namei.c Fri Nov 29 18:11:18 2002 -@@ -94,6 +94,12 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct dentry *de, struct lookup_intent *it) -+{ -+ if (it && de->d_op && de->d_op->d_intent_release) -+ de->d_op->d_intent_release(de, it); -+} -+ - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the - * kernel data space before using them.. -@@ -260,10 +266,19 @@ - * Internal lookup() using the new generic dcache. - * SMP-safe - */ --static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * dentry = d_lookup(parent, name); - -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { -+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -281,7 +296,8 @@ - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; -@@ -300,6 +316,9 @@ - result = ERR_PTR(-ENOMEM); - if (dentry) { - lock_kernel(); -+ if (dir->i_op->lookup2) -+ result = dir->i_op->lookup2(dir, dentry, it); -+ else - result = dir->i_op->lookup(dir, dentry); - unlock_kernel(); - if (result) -@@ -321,6 +340,12 @@ - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate2) { -+ if (!result->d_op->d_revalidate2(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ result = ERR_PTR(-ENOENT); -+ } - } - return result; - } -@@ -332,7 +357,8 @@ - * Without that kind of total limit, nasty chains of consecutive - * symlinks can cause almost arbitrarily long lookups. - */ --static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) -+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, -+ struct lookup_intent *it) - { - int err; - if (current->link_count >= 5) -@@ -346,10 +372,14 @@ - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -- err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -+ intent_release(dentry, it); - path_release(nd); - return -ELOOP; - } -@@ -445,7 +475,8 @@ - * - * We expect 'base' to be positive and a directory. - */ --int link_path_walk(const char * name, struct nameidata *nd) -+int link_path_walk_it(const char *name, struct nameidata *nd, -+ struct lookup_intent *it) - { - struct dentry *dentry; - struct inode *inode; -@@ -518,9 +549,9 @@ - break; - } - /* This does the actual lookups.. */ -- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - if (!dentry) { -- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; -@@ -537,8 +568,8 @@ - if (!inode->i_op) - goto out_dput; - -- if (inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ if (inode->i_op->follow_link || inode->i_op->follow_link2) { -+ err = do_follow_link(dentry, nd, NULL); - dput(dentry); - if (err) - goto return_err; -@@ -554,7 +585,7 @@ - nd->dentry = dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup2) - break; - continue; - /* here ends the main loop */ -@@ -581,9 +612,9 @@ - if (err < 0) - break; - } -- dentry = cached_lookup(nd->dentry, &this, 0); -+ dentry = cached_lookup(nd->dentry, &this, 0, it); - if (!dentry) { -- dentry = real_lookup(nd->dentry, &this, 0); -+ dentry = real_lookup(nd->dentry, &this, 0, it); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; -@@ -591,9 +622,9 @@ - while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry)) - ; - inode = dentry->d_inode; -- if ((lookup_flags & LOOKUP_FOLLOW) -- && inode && inode->i_op && inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op && -+ (inode->i_op->follow_link || inode->i_op->follow_link2)) { -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -607,7 +638,8 @@ - goto no_inode; - if (lookup_flags & LOOKUP_DIRECTORY) { - err = -ENOTDIR; -- if (!inode->i_op || !inode->i_op->lookup) -+ if (!inode->i_op || -+ (!inode->i_op->lookup && !inode->i_op->lookup2)) - break; - } - goto return_base; -@@ -636,10 +668,21 @@ - return err; - } - -+int link_path_walk(const char * name, struct nameidata *nd) -+{ -+ return link_path_walk_it(name, nd, NULL); -+} -+ -+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it) -+{ -+ current->total_link_count = 0; -+ return link_path_walk_it(name, nd, it); -+} -+ - int path_walk(const char * name, struct nameidata *nd) - { - current->total_link_count = 0; -- return link_path_walk(name, nd); -+ return link_path_walk_it(name, nd, NULL); - } - - /* SMP-safe */ -@@ -742,7 +785,8 @@ - * needs parent already locked. Doesn't follow mounts. - * SMP-safe. - */ --struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, -+ struct lookup_intent *it) - { - struct dentry * dentry; - struct inode *inode; -@@ -765,13 +809,16 @@ - goto out; - } - -- dentry = cached_lookup(base, name, 0); -+ dentry = cached_lookup(base, name, 0, it); - if (!dentry) { - struct dentry *new = d_alloc(base, name); - dentry = ERR_PTR(-ENOMEM); - if (!new) - goto out; - lock_kernel(); -+ if (inode->i_op->lookup2) -+ dentry = inode->i_op->lookup2(inode, new, it); -+ else - dentry = inode->i_op->lookup(inode, new); - unlock_kernel(); - if (!dentry) -@@ -783,6 +830,12 @@ - return dentry; - } - -+struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+{ -+ return lookup_hash_it(name, base, NULL); -+} -+ -+ - /* SMP-safe */ - struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) - { -@@ -804,7 +857,7 @@ - } - this.hash = end_name_hash(hash); - -- return lookup_hash(&this, base); -+ return lookup_hash_it(&this, base, NULL); - access: - return ERR_PTR(-EACCES); - } -@@ -836,6 +889,23 @@ - return err; - } - -+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it) -+{ -+ char *tmp; -+ int err; -+ -+ tmp = getname(name); -+ err = PTR_ERR(tmp); -+ if (!IS_ERR(tmp)) { -+ err = 0; -+ if (path_init(tmp, flags, nd)) -+ err = path_walk_it(tmp, nd, it); -+ putname(tmp); -+ } -+ return err; -+} -+ - /* - * It's inline, so penalty for filesystems that don't use sticky bit is - * minimal. -@@ -970,7 +1040,8 @@ - * for symlinks (where the permissions are checked later). - * SMP-safe - */ --int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) -+int open_namei_it(const char *pathname, int flag, int mode, -+ struct nameidata *nd, struct lookup_intent *it) - { - int acc_mode, error = 0; - struct inode *inode; -@@ -985,7 +1056,7 @@ - */ - if (!(flag & O_CREAT)) { - if (path_init(pathname, lookup_flags(flag), nd)) -- error = path_walk(pathname, nd); -+ error = path_walk_it(pathname, nd, it); - if (error) - return error; - dentry = nd->dentry; -@@ -995,6 +1066,10 @@ - /* - * Create - we need to know the parent. - */ -+ if (it) { -+ it->it_mode = mode; -+ it->it_op |= IT_CREAT; -+ } - if (path_init(pathname, LOOKUP_PARENT, nd)) - error = path_walk(pathname, nd); - if (error) -@@ -1011,7 +1086,7 @@ - - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - - do_last: - error = PTR_ERR(dentry); -@@ -1020,6 +1095,7 @@ - goto exit; - } - -+ it->it_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { - if (!IS_POSIX_ACL(dir->d_inode)) -@@ -1054,7 +1130,8 @@ - error = -ENOENT; - if (!dentry->d_inode) - goto exit_dput; -- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) -+ if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || -+ dentry->d_inode->i_op->follow_link2)) - goto do_link; - - dput(nd->dentry); -@@ -1140,8 +1217,10 @@ - return 0; - - exit_dput: -+ intent_release(dentry, it); - dput(dentry); - exit: -+ intent_release(nd->dentry, it); - path_release(nd); - return error; - -@@ -1160,7 +1239,12 @@ - * are done. Procfs-like symlinks just set LAST_BIND. - */ - UPDATE_ATIME(dentry->d_inode); -- error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ error = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (error) -+ intent_release(dentry, it); - dput(dentry); - if (error) - return error; -@@ -1182,13 +1266,20 @@ - } - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - putname(nd->last.name); - goto do_last; - } - -+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd) -+{ -+ return open_namei_it(pathname, flag, mode, nd, NULL); -+} -+ -+ - /* SMP-safe */ --static struct dentry *lookup_create(struct nameidata *nd, int is_dir) -+static struct dentry *lookup_create(struct nameidata *nd, int is_dir, -+ struct lookup_intent *it) - { - struct dentry *dentry; - -@@ -1196,7 +1287,7 @@ - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - if (IS_ERR(dentry)) - goto fail; - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) -@@ -1242,6 +1333,7 @@ - char * tmp; - struct dentry * dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode }; - - if (S_ISDIR(mode)) - return -EPERM; -@@ -1253,7 +1345,7 @@ - error = path_walk(tmp, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(dentry); - - if (!IS_POSIX_ACL(nd.dentry->d_inode)) -@@ -1272,6 +1364,7 @@ - default: - error = -EINVAL; - } -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1312,6 +1405,7 @@ - { - int error = 0; - char * tmp; -+ struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode }; - - tmp = getname(pathname); - error = PTR_ERR(tmp); -@@ -1323,12 +1417,13 @@ - error = path_walk(tmp, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 1); -+ dentry = lookup_create(&nd, 1, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - if (!IS_POSIX_ACL(nd.dentry->d_inode)) - mode &= ~current->fs->umask; - error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1410,6 +1505,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_RMDIR }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1432,10 +1528,11 @@ - goto exit1; - } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1479,6 +1576,7 @@ - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_UNLINK }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1492,7 +1590,7 @@ - if (nd.last_type != LAST_NORM) - goto exit1; - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - /* Why not before? Because we want correct error value */ -@@ -1500,6 +1598,7 @@ - goto slashes; - error = vfs_unlink(nd.dentry->d_inode, dentry); - exit2: -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1546,6 +1645,7 @@ - int error = 0; - char * from; - char * to; -+ struct lookup_intent it = { .it_op = IT_SYMLINK }; - - from = getname(oldname); - if(IS_ERR(from)) -@@ -1560,10 +1660,12 @@ - error = path_walk(to, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ it.it_data = from; -+ dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_symlink(nd.dentry->d_inode, dentry, from); -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1629,6 +1731,7 @@ - int error; - char * from; - char * to; -+ struct lookup_intent it = { .it_op = IT_LINK }; - - from = getname(oldname); - if(IS_ERR(from)) -@@ -1641,7 +1744,7 @@ - - error = 0; - if (path_init(from, LOOKUP_POSITIVE, &old_nd)) -- error = path_walk(from, &old_nd); -+ error = path_walk_it(from, &old_nd, &it); - if (error) - goto exit; - if (path_init(to, LOOKUP_PARENT, &nd)) -@@ -1651,10 +1754,12 @@ - error = -EXDEV; - if (old_nd.mnt != nd.mnt) - goto out_release; -- new_dentry = lookup_create(&nd, 0); -+ it.it_op = IT_LINK2; -+ new_dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(new_dentry); - if (!IS_ERR(new_dentry)) { - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); -+ intent_release(new_dentry, &it); - dput(new_dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1697,7 +1802,8 @@ - * locking]. - */ - int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - struct inode *target; -@@ -1757,6 +1863,7 @@ - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - if (target) { - if (!error) - target->i_flags |= S_DEAD; -@@ -1778,7 +1885,8 @@ - } - - int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - -@@ -1809,6 +1917,7 @@ - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - double_up(&old_dir->i_zombie, &new_dir->i_zombie); - if (error) - return error; -@@ -1820,13 +1929,14 @@ - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - if (S_ISDIR(old_dentry->d_inode->i_mode)) -- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); - else -- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); - if (!error) { - if (old_dir == new_dir) - inode_dir_notify(old_dir, DN_RENAME); -@@ -1843,6 +1953,7 @@ - int error = 0; - struct dentry * old_dir, * new_dir; - struct dentry * old_dentry, *new_dentry; -+ struct lookup_intent it = { .it_op = IT_RENAME }; - struct nameidata oldnd, newnd; - - if (path_init(oldname, LOOKUP_PARENT, &oldnd)) -@@ -1871,7 +1982,7 @@ - - double_lock(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -1887,18 +1998,21 @@ - if (newnd.last.name[newnd.last.len]) - goto exit4; - } -- new_dentry = lookup_hash(&newnd.last, new_dir); -+ it.it_op = IT_RENAME2; -+ new_dentry = lookup_hash_it(&newnd.last, new_dir, &it); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; - - lock_kernel(); - error = vfs_rename(old_dir->d_inode, old_dentry, -- new_dir->d_inode, new_dentry); -+ new_dir->d_inode, new_dentry, &it); - unlock_kernel(); - -+ intent_release(new_dentry, &it); - dput(new_dentry); - exit4: -+ intent_release(old_dentry, &it); - dput(old_dentry); - exit3: - double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); -@@ -1947,7 +2061,8 @@ - } - - static inline int --__vfs_follow_link(struct nameidata *nd, const char *link) -+__vfs_follow_link(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) - { - int res = 0; - char *name; -@@ -1960,7 +2075,7 @@ - /* weird __emul_prefix() stuff did it */ - goto out; - } -- res = link_path_walk(link, nd); -+ res = link_path_walk_it(link, nd, it); - out: - if (current->link_count || res || nd->last_type!=LAST_NORM) - return res; -@@ -1982,7 +2097,13 @@ - - int vfs_follow_link(struct nameidata *nd, const char *link) - { -- return __vfs_follow_link(nd, link); -+ return __vfs_follow_link(nd, link, NULL); -+} -+ -+int vfs_follow_link_it(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) -+{ -+ return __vfs_follow_link(nd, link, it); - } - - /* get the link contents into pagecache */ -@@ -2024,7 +2145,7 @@ - { - struct page *page = NULL; - char *s = page_getlink(dentry, &page); -- int res = __vfs_follow_link(nd, s); -+ int res = __vfs_follow_link(nd, s, NULL); - if (page) { - kunmap(page); - page_cache_release(page); ---- linux-pristine/./fs/open.c Thu Dec 5 10:49:20 2002 -+++ linux/./fs/open.c Fri Nov 29 18:06:21 2002 -@@ -19,6 +19,9 @@ - #include - - #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) -+extern int path_walk_it(const char *name, struct nameidata *nd, -+ struct lookup_intent *it); -+extern void intent_release(struct dentry *de, struct lookup_intent *it); - - int vfs_statfs(struct super_block *sb, struct statfs *buf) - { -@@ -94,12 +97,13 @@ - struct nameidata nd; - struct inode * inode; - int error; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - - error = -EINVAL; - if (length < 0) /* sorry, but loff_t says... */ - goto out; - -- error = user_path_walk(path, &nd); -+ error = user_path_walk_it(path, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -144,6 +148,7 @@ - put_write_access(inode); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -235,8 +240,9 @@ - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -262,6 +268,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -279,8 +286,9 @@ - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - - if (error) - goto out; -@@ -307,6 +315,7 @@ - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -323,6 +332,7 @@ - int old_fsuid, old_fsgid; - kernel_cap_t old_cap; - int res; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ - return -EINVAL; -@@ -340,13 +350,14 @@ - else - current->cap_effective = current->cap_permitted; - -- res = user_path_walk(filename, &nd); -+ res = user_path_walk_it(filename, &nd, &it); - if (!res) { - res = permission(nd.dentry->d_inode, mode); - /* SuS v2 requires we report a read only fs too */ - if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) - && !special_file(nd.dentry->d_inode->i_mode)) - res = -EROFS; -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - -@@ -362,6 +373,7 @@ - int error; - struct nameidata nd; - char *name; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - name = getname(filename); - error = PTR_ERR(name); -@@ -370,7 +382,7 @@ - - error = 0; - if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd)) -- error = path_walk(name, &nd); -+ error = path_walk_it(name, &nd, &it); - putname(name); - if (error) - goto out; -@@ -382,6 +394,7 @@ - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -422,6 +435,7 @@ - int error; - struct nameidata nd; - char *name; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - name = getname(filename); - error = PTR_ERR(name); -@@ -430,7 +444,7 @@ - - path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW | - LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); -- error = path_walk(name, &nd); -+ error = path_walk_it(name, &nd, &it); - putname(name); - if (error) - goto out; -@@ -447,6 +461,7 @@ - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -491,8 +506,9 @@ - struct inode * inode; - int error; - struct iattr newattrs; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -512,6 +528,7 @@ - error = notify_change(nd.dentry, &newattrs); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -581,10 +598,12 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = chown_common(nd.dentry, user, group); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -594,10 +613,12 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = chown_common(nd.dentry, user, group); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -631,10 +652,16 @@ - * for the internal routines (ie open_namei()/follow_link() etc). 00 is - * used by symlinks. - */ -+extern int open_namei_it(const char *filename, int namei_flags, int mode, -+ struct nameidata *nd, struct lookup_intent *it); -+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it); -+ - struct file *filp_open(const char * filename, int flags, int mode) - { - int namei_flags, error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_OPEN }; - - namei_flags = flags; - if ((namei_flags+1) & O_ACCMODE) -@@ -642,14 +669,15 @@ - if (namei_flags & O_TRUNC) - namei_flags |= 2; - -- error = open_namei(filename, namei_flags, mode, &nd); -- if (!error) -- return dentry_open(nd.dentry, nd.mnt, flags); -+ error = open_namei_it(filename, namei_flags, mode, &nd, &it); -+ if (error) -+ return ERR_PTR(error); - -- return ERR_PTR(error); -+ return dentry_open_it(nd.dentry, nd.mnt, flags, &it); - } - --struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it) - { - struct file * f; - struct inode *inode; -@@ -692,6 +720,7 @@ - } - f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); - -+ intent_release(dentry, it); - return f; - - cleanup_all: -@@ -706,11 +735,17 @@ - cleanup_file: - put_filp(f); - cleanup_dentry: -+ intent_release(dentry, it); - dput(dentry); - mntput(mnt); - return ERR_PTR(error); - } - -+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+{ -+ return dentry_open_it(dentry, mnt, flags, NULL); -+} -+ - /* - * Find an empty file descriptor entry, and mark it busy. - */ ---- linux-pristine/./fs/stat.c Thu Dec 5 10:49:22 2002 -+++ linux/./fs/stat.c Fri Nov 29 18:06:21 2002 -@@ -13,6 +13,7 @@ - - #include - -+extern void intent_release(struct dentry *de, struct lookup_intent *it); - /* - * Revalidate the inode. This is required for proper NFS attribute caching. - */ -@@ -135,13 +136,15 @@ - asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -151,13 +154,15 @@ - asmlinkage long sys_newstat(char * filename, struct stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -172,13 +177,15 @@ - asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -189,13 +196,15 @@ - asmlinkage long sys_newlstat(char * filename, struct stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -247,20 +256,21 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_READLINK }; - - if (bufsiz <= 0) - return -EINVAL; - -- error = user_path_walk_link(path, &nd); -+ error = user_path_walk_link_it(path, &nd, &it); - if (!error) { - struct inode * inode = nd.dentry->d_inode; -- - error = -EINVAL; - if (inode->i_op && inode->i_op->readlink && - !(error = do_revalidate(nd.dentry))) { - UPDATE_ATIME(inode); - error = inode->i_op->readlink(nd.dentry, buf, bufsiz); - } -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -333,12 +343,14 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -348,12 +360,14 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; ---- linux-pristine/./mm/slab.c Thu Dec 5 10:50:02 2002 -+++ linux/./mm/slab.c Fri Nov 29 18:06:21 2002 -@@ -1187,6 +1187,59 @@ - * Called with the cache-lock held. - */ - -+extern struct page *check_get_page(unsigned long kaddr); -+struct page *page_mem_map(struct page *page); -+static int kmem_check_cache_obj (kmem_cache_t * cachep, -+ slab_t *slabp, void * objp) -+{ -+ int i; -+ unsigned int objnr; -+ -+#if DEBUG -+ if (cachep->flags & SLAB_RED_ZONE) { -+ objp -= BYTES_PER_WORD; -+ if ( *(unsigned long *)objp != RED_MAGIC2) -+ /* Either write before start, or a double free. */ -+ return 0; -+ if (*(unsigned long *)(objp+cachep->objsize - -+ BYTES_PER_WORD) != RED_MAGIC2) -+ /* Either write past end, or a double free. */ -+ return 0; -+ } -+#endif -+ -+ objnr = (objp-slabp->s_mem)/cachep->objsize; -+ if (objnr >= cachep->num) -+ return 0; -+ if (objp != slabp->s_mem + objnr*cachep->objsize) -+ return 0; -+ -+ /* Check slab's freelist to see if this obj is there. */ -+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { -+ if (i == objnr) -+ return 0; -+ } -+ return 1; -+} -+ -+ -+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) -+{ -+ struct page *page = check_get_page((unsigned long)objp); -+ -+ if (!VALID_PAGE(page)) -+ return 0; -+ -+ if (!PageSlab(page)) -+ return 0; -+ -+ /* XXX check for freed slab objects ? */ -+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) -+ return 0; -+ -+ return (cachep == GET_PAGE_CACHE(page)); -+} -+ - #if DEBUG - static int kmem_extra_free_checks (kmem_cache_t * cachep, - slab_t *slabp, void * objp) diff --git a/lustre/kernel_patches/patches/uml_check_get_page.patch b/lustre/kernel_patches/patches/uml_check_get_page.patch deleted file mode 100644 index fafdf90..0000000 --- a/lustre/kernel_patches/patches/uml_check_get_page.patch +++ /dev/null @@ -1,31 +0,0 @@ - - - - 0 files changed - ---- linux-2.4.18-17.8.0/arch/um/kernel/mem.c~uml_check_get_page 2002-12-06 14:52:30.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/arch/um/kernel/mem.c 2002-12-06 14:52:30.000000000 -0800 -@@ -529,6 +529,21 @@ struct page *pte_mem_map(pte_t pte) - return(phys_mem_map(pte_val(pte))); - } - -+struct page *check_get_page(unsigned long kaddr) -+{ -+ struct page *page; -+ struct mem_region *mr; -+ unsigned long phys = __pa(kaddr); -+ unsigned int n = phys_region_index(phys); -+ -+ if (regions[n] == NULL) -+ return NULL; -+ -+ mr = regions[n]; -+ page = (struct page *) mr->mem_map; -+ return page + ((phys_addr(phys)) >> PAGE_SHIFT); -+} -+ - struct mem_region *page_region(struct page *page, int *index_out) - { - int i; - -_ diff --git a/lustre/kernel_patches/patches/uml_compile_fixes.patch b/lustre/kernel_patches/patches/uml_compile_fixes.patch deleted file mode 100644 index 815bd92..0000000 --- a/lustre/kernel_patches/patches/uml_compile_fixes.patch +++ /dev/null @@ -1,18 +0,0 @@ - - - - 0 files changed - ---- linux-2.4.18-17.8.0/include/asm-um/pgtable.h~uml_compile_fixes 2002-12-06 15:46:21.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/include/asm-um/pgtable.h 2002-12-06 15:46:21.000000000 -0800 -@@ -200,7 +200,7 @@ static inline void pgd_clear(pgd_t * pgd - * called on a highmem page. - */ - --#define page_address(page) ({ if (!(page)->virtual) BUG(); (page)->virtual; }) -+//#define page_address(page) ({ if (!(page)->virtual) BUG(); (page)->virtual; }) - #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) - - extern struct page *pte_mem_map(pte_t pte); - -_ diff --git a/lustre/kernel_patches/patches/uml_no_panic.patch b/lustre/kernel_patches/patches/uml_no_panic.patch deleted file mode 100644 index b0c305b..0000000 --- a/lustre/kernel_patches/patches/uml_no_panic.patch +++ /dev/null @@ -1,31 +0,0 @@ - - - - 0 files changed - ---- linux-2.4.18-17.8.0/arch/um/kernel/mem.c~uml_no_panic 2002-12-06 14:52:30.000000000 -0800 -+++ linux-2.4.18-17.8.0-zab/arch/um/kernel/mem.c 2002-12-06 14:52:30.000000000 -0800 -@@ -559,7 +559,9 @@ struct mem_region *page_region(struct pa - return(region); - } - } -- panic("No region found for page"); -+// panic("No region found for page"); -+ printk(KERN_ERR "no region foudn for page %p\n, returning NULL\n", -+ page); - return(NULL); - } - -@@ -581,7 +583,9 @@ unsigned long region_pa(void *virt) - (addr <= region->start + region->len)) - return(mk_phys(addr - region->start, i)); - } -- panic("region_pa : no region for virtual address"); -+ //panic("region_pa : no region for virtual address"); -+ printk(KERN_ERR "no region for virtual address %lu, return pa 0\n", -+ addr); - return(0); - } - - -_ diff --git a/lustre/kernel_patches/patches/vanilla-2.4.18.patch b/lustre/kernel_patches/patches/vanilla-2.4.18.patch deleted file mode 100644 index 00cc57c..0000000 --- a/lustre/kernel_patches/patches/vanilla-2.4.18.patch +++ /dev/null @@ -1,1672 +0,0 @@ ---- lum-pristine/include/linux/lustre_version.h Wed Dec 31 19:00:00 1969 -+++ lum/include/linux/lustre_version.h Tue Nov 26 07:02:14 2002 -@@ -0,0 +1,1 @@ -+#define LUSTRE_KERNEL_VERSION 5 ---- 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 -@@ -260,6 +260,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); -@@ -271,6 +272,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 *); -@@ -850,6 +854,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 *); -@@ -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 *); -@@ -1422,6 +1428,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; ---- 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,12 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct dentry *de, struct lookup_intent *it) -+{ -+ if (it && de->d_op && de->d_op->d_intent_release) -+ de->d_op->d_intent_release(de, it); -+} -+ - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the - * kernel data space before using them.. -@@ -260,10 +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; - } -@@ -334,7 +361,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 +376,14 @@ - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -- err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -+ intent_release(dentry, it); - path_release(nd); - return -ELOOP; - } -@@ -445,7 +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; -@@ -537,8 +570,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, NULL); - dput(dentry); - if (err) - goto return_err; -@@ -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; -@@ -591,9 +625,9 @@ - while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry)) - ; - inode = dentry->d_inode; -- if ((lookup_flags & LOOKUP_FOLLOW) -- && inode && inode->i_op && inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op && -+ (inode->i_op->follow_link || inode->i_op->follow_link2)) { -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -607,7 +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, -@@ -1053,7 +1134,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); -@@ -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,7 +1242,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; -@@ -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, 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; - -@@ -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); - dput(old_dentry); - exit3: - double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); -@@ -1965,7 +2094,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 +2108,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 +2130,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 +2178,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); ---- 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/kernel_patches/patches/vanilla-2.4.19.patch b/lustre/kernel_patches/patches/vanilla-2.4.19.patch deleted file mode 100644 index 4ed5bb9..0000000 --- a/lustre/kernel_patches/patches/vanilla-2.4.19.patch +++ /dev/null @@ -1,1576 +0,0 @@ - - - - arch/i386/mm/init.c | 6 - arch/ia64/mm/init.c | 6 - drivers/block/blkpg.c | 35 ++++ - drivers/block/loop.c | 5 - drivers/ide/ide-disk.c | 6 - fs/dcache.c | 1 - fs/ext3/Makefile | 2 - fs/ext3/super.c | 2 - fs/namei.c | 296 ++++++++++++++++++++++++++++++++++------- - fs/nfsd/vfs.c | 2 - fs/open.c | 63 ++++++-- - fs/stat.c | 30 +++- - include/linux/blkdev.h | 4 - include/linux/dcache.h | 31 ++++ - include/linux/fs.h | 23 +++ - include/linux/lustre_version.h | 1 - include/linux/slab.h | 1 - kernel/ksyms.c | 7 - mm/slab.c | 53 +++++++ - 19 files changed, 501 insertions(+), 73 deletions(-) - ---- /dev/null Fri Aug 30 17:31:37 2002 -+++ linux-2.4.19-root/include/linux/lustre_version.h Sun Jan 19 19:54:00 2003 -@@ -0,0 +1 @@ -+#define LUSTRE_KERNEL_VERSION 7 ---- linux-2.4.19/arch/ia64/mm/init.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/arch/ia64/mm/init.c Sun Jan 19 19:46:42 2003 -@@ -37,6 +37,12 @@ unsigned long MAX_DMA_ADDRESS = PAGE_OFF - - static unsigned long totalram_pages; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int - do_check_pgt_cache (int low, int high) - { ---- linux-2.4.19/arch/i386/mm/init.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/arch/i386/mm/init.c Sun Jan 19 19:46:42 2003 -@@ -43,6 +43,12 @@ unsigned long highstart_pfn, highend_pfn - static unsigned long totalram_pages; - static unsigned long totalhigh_pages; - -+struct page *check_get_page(unsigned long kaddr) -+{ -+#warning FIXME: Lustre team, is this solid? -+ return virt_to_page(kaddr); -+} -+ - int do_check_pgt_cache(int low, int high) - { - int freed = 0; ---- linux-2.4.19/drivers/block/blkpg.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/drivers/block/blkpg.c Sun Jan 19 19:46:42 2003 -@@ -296,3 +296,38 @@ int blk_ioctl(kdev_t dev, unsigned int c - } - - EXPORT_SYMBOL(blk_ioctl); -+ -+#define NUM_DEV_NO_WRITE 16 -+static int dev_no_write[NUM_DEV_NO_WRITE]; -+ -+/* -+ * Debug code for turning block devices "read-only" (will discard writes -+ * silently). This is for filesystem crash/recovery testing. -+ */ -+void dev_set_rdonly(kdev_t dev, int no_write) -+{ -+ if (dev) { -+ printk(KERN_WARNING "Turning device %s read-only\n", -+ bdevname(dev)); -+ dev_no_write[no_write] = 0xdead0000 + dev; -+ } -+} -+ -+int dev_check_rdonly(kdev_t dev) { -+ int i; -+ -+ for (i = 0; i < NUM_DEV_NO_WRITE; i++) { -+ if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 && -+ dev == (dev_no_write[i] & 0xffff)) -+ return 1; -+ } -+ return 0; -+} -+ -+void dev_clear_rdonly(int no_write) { -+ dev_no_write[no_write] = 0; -+} -+ -+EXPORT_SYMBOL(dev_set_rdonly); -+EXPORT_SYMBOL(dev_check_rdonly); -+EXPORT_SYMBOL(dev_clear_rdonly); ---- linux-2.4.19/drivers/block/loop.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/drivers/block/loop.c Sun Jan 19 19:46:42 2003 -@@ -474,6 +474,11 @@ static int loop_make_request(request_que - spin_unlock_irq(&lo->lo_lock); - - if (rw == WRITE) { -+#ifdef CONFIG_DEV_RDONLY -+ if (dev_check_rdonly(rbh->b_rdev)) -+ goto err; -+#endif -+ - if (lo->lo_flags & LO_FLAGS_READ_ONLY) - goto err; - } else if (rw == READA) { ---- linux-2.4.19/drivers/ide/ide-disk.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/drivers/ide/ide-disk.c Sun Jan 19 19:46:42 2003 -@@ -551,6 +551,12 @@ static ide_startstop_t lba_48_rw_disk (i - */ - static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) - { -+#ifdef CONFIG_DEV_RDONLY -+ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { -+ ide_end_request(1, HWGROUP(drive)); -+ return ide_stopped; -+ } -+#endif - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl,IDE_CONTROL_REG); - ---- linux-2.4.19/fs/ext3/Makefile~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/fs/ext3/Makefile Sun Jan 19 19:46:42 2003 -@@ -9,6 +9,8 @@ - - O_TARGET := ext3.o - -+export-objs := super.o -+ - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o - obj-m := $(O_TARGET) ---- linux-2.4.19/fs/ext3/super.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/fs/ext3/super.c Sun Jan 19 19:46:42 2003 -@@ -1744,7 +1744,7 @@ static void __exit exit_ext3_fs(void) - unregister_filesystem(&ext3_fs_type); - } - --EXPORT_NO_SYMBOLS; -+EXPORT_SYMBOL(ext3_bread); - - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); - MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); ---- linux-2.4.19/include/linux/blkdev.h~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/include/linux/blkdev.h Sun Jan 19 21:05:55 2003 -@@ -240,4 +240,8 @@ static inline unsigned int block_size(kd - 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.19/include/linux/slab.h~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/include/linux/slab.h Sun Jan 19 21:05:52 2003 -@@ -57,6 +57,7 @@ extern int kmem_cache_destroy(kmem_cache - extern int kmem_cache_shrink(kmem_cache_t *); - extern void *kmem_cache_alloc(kmem_cache_t *, int); - extern void kmem_cache_free(kmem_cache_t *, void *); -+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); - - extern void *kmalloc(size_t, int); - extern void kfree(const void *); ---- linux-2.4.19/kernel/ksyms.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/kernel/ksyms.c Sun Jan 19 19:46:42 2003 -@@ -264,6 +264,7 @@ EXPORT_SYMBOL(read_cache_page); - EXPORT_SYMBOL(set_page_dirty); - EXPORT_SYMBOL(vfs_readlink); - EXPORT_SYMBOL(vfs_follow_link); -+EXPORT_SYMBOL(vfs_follow_link_it); - EXPORT_SYMBOL(page_readlink); - EXPORT_SYMBOL(page_follow_link); - EXPORT_SYMBOL(page_symlink_inode_operations); -@@ -280,6 +281,12 @@ EXPORT_SYMBOL(dcache_dir_fsync); - EXPORT_SYMBOL(dcache_readdir); - EXPORT_SYMBOL(dcache_dir_ops); - -+/* 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.19/include/linux/dcache.h~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/include/linux/dcache.h Sun Jan 19 19:46:42 2003 -@@ -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 @@ struct dentry { - unsigned long d_time; /* used by d_revalidate */ - struct dentry_operations *d_op; - struct super_block * d_sb; /* The root of the dentry tree */ -+ struct lookup_intent *d_it; - unsigned long d_vfs_flags; - void * d_fsdata; /* fs-specific data */ - unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */ -@@ -90,6 +119,8 @@ struct dentry_operations { - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); -+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); - }; - - /* the dentry parameter passed to d_hash and d_compare is the parent ---- linux-2.4.19/include/linux/fs.h~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/include/linux/fs.h Sun Jan 19 21:05:40 2003 -@@ -541,6 +541,7 @@ struct file { - - /* needed for tty driver, and maybe others */ - void *private_data; -+ struct lookup_intent *f_intent; - - /* preallocated helper kiobuf to speedup O_DIRECT */ - struct kiobuf *f_iobuf; -@@ -792,7 +793,9 @@ extern int vfs_symlink(struct inode *, s - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it); - - /* - * File types -@@ -853,16 +856,28 @@ struct file_operations { - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *); - int (*link) (struct dentry *,struct inode *,struct dentry *); -+ int (*link2) (struct inode *,struct inode *, const char *, int); - int (*unlink) (struct inode *,struct dentry *); -+ int (*unlink2) (struct inode *, char *, int); - int (*symlink) (struct inode *,struct dentry *,const char *); -+ int (*symlink2) (struct inode *,const char *, int, const char *); - int (*mkdir) (struct inode *,struct dentry *,int); -+ int (*mkdir2) (struct inode *,char *, int,int); - int (*rmdir) (struct inode *,struct dentry *); -+ int (*rmdir2) (struct inode *, char *, int); - int (*mknod) (struct inode *,struct dentry *,int,int); -+ int (*mknod2) (struct inode *,char *, int,int,int); - int (*rename) (struct inode *, struct dentry *, - struct inode *, struct dentry *); -+ int (*rename2) (struct inode *, struct inode *, -+ char *oldname, int oldlen, -+ char *newname, int newlen); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); -+ int (*follow_link2) (struct dentry *, struct nameidata *, -+ struct lookup_intent *it); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*revalidate) (struct dentry *); -@@ -999,6 +1014,7 @@ extern int unregister_filesystem(struct - extern struct vfsmount *kern_mount(struct file_system_type *); - extern int may_umount(struct vfsmount *); - extern long do_mount(char *, char *, char *, unsigned long, void *); -+struct vfsmount *do_kern_mount(const char *fstype, int flags, char *name, void *data); - extern void umount_tree(struct vfsmount *); - - #define kern_umount mntput -@@ -1329,6 +1345,7 @@ typedef int (*read_actor_t)(read_descrip - extern loff_t default_llseek(struct file *file, loff_t offset, int origin); - - extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *)); -+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it)); - extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *)); - extern int FASTCALL(path_walk(const char *, struct nameidata *)); - extern int FASTCALL(link_path_walk(const char *, struct nameidata *)); -@@ -1339,6 +1356,8 @@ extern struct dentry * lookup_one_len(co - extern struct dentry * lookup_hash(struct qstr *, struct dentry *); - #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) - #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) -+#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it) -+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it) - - extern void iput(struct inode *); - extern void force_delete(struct inode *); -@@ -1448,6 +1467,8 @@ extern struct file_operations generic_ro - - extern int vfs_readlink(struct dentry *, char *, int, const char *); - extern int vfs_follow_link(struct nameidata *, const char *); -+extern int vfs_follow_link_it(struct nameidata *, const char *, -+ struct lookup_intent *it); - extern int page_readlink(struct dentry *, char *, int); - extern int page_follow_link(struct dentry *, struct nameidata *); - extern struct inode_operations page_symlink_inode_operations; ---- linux-2.4.19/fs/dcache.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/fs/dcache.c Sun Jan 19 19:46:42 2003 -@@ -616,6 +616,7 @@ struct dentry * d_alloc(struct dentry * - dentry->d_op = NULL; - dentry->d_fsdata = NULL; - dentry->d_mounted = 0; -+ dentry->d_it = NULL; - INIT_LIST_HEAD(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); ---- linux-2.4.19/fs/nfsd/vfs.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/fs/nfsd/vfs.c Sun Jan 19 19:46:42 2003 -@@ -1295,7 +1295,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); - nfsd_sync_dir(fdentry); ---- linux-2.4.19/fs/namei.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/fs/namei.c Sun Jan 19 19:46:42 2003 -@@ -94,6 +94,12 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct dentry *de, struct lookup_intent *it) -+{ -+ if (it && de->d_op && de->d_op->d_intent_release) -+ de->d_op->d_intent_release(de, it); -+} -+ - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the - * kernel data space before using them.. -@@ -260,10 +266,19 @@ void path_release(struct nameidata *nd) - * Internal lookup() using the new generic dcache. - * SMP-safe - */ --static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * dentry = d_lookup(parent, name); - -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { -+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -281,7 +296,8 @@ static struct dentry * cached_lookup(str - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; -@@ -300,6 +316,9 @@ static struct dentry * real_lookup(struc - result = ERR_PTR(-ENOMEM); - if (dentry) { - lock_kernel(); -+ if (dir->i_op->lookup2) -+ result = dir->i_op->lookup2(dir, dentry, it); -+ else - result = dir->i_op->lookup(dir, dentry); - unlock_kernel(); - if (result) -@@ -321,6 +340,12 @@ static struct dentry * real_lookup(struc - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate2) { -+ if (!result->d_op->d_revalidate2(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ result = ERR_PTR(-ENOENT); -+ } - } - return result; - } -@@ -332,7 +357,8 @@ static struct dentry * real_lookup(struc - * Without that kind of total limit, nasty chains of consecutive - * symlinks can cause almost arbitrarily long lookups. - */ --static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) -+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, -+ struct lookup_intent *it) - { - int err; - if (current->link_count >= 5) -@@ -346,10 +372,14 @@ static inline int do_follow_link(struct - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -- err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -+ intent_release(dentry, it); - path_release(nd); - return -ELOOP; - } -@@ -447,7 +477,8 @@ static inline void follow_dotdot(struct - * - * We expect 'base' to be positive and a directory. - */ --int link_path_walk(const char * name, struct nameidata *nd) -+int link_path_walk_it(const char *name, struct nameidata *nd, -+ struct lookup_intent *it) - { - struct dentry *dentry; - struct inode *inode; -@@ -520,9 +551,9 @@ int link_path_walk(const char * name, st - break; - } - /* This does the actual lookups.. */ -- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - if (!dentry) { -- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; -@@ -539,8 +570,8 @@ int link_path_walk(const char * name, st - if (!inode->i_op) - goto out_dput; - -- if (inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ if (inode->i_op->follow_link || inode->i_op->follow_link2) { -+ err = do_follow_link(dentry, nd, NULL); - dput(dentry); - if (err) - goto return_err; -@@ -556,7 +587,7 @@ int link_path_walk(const char * name, st - nd->dentry = dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup2) - break; - continue; - /* here ends the main loop */ -@@ -583,9 +614,9 @@ last_component: - if (err < 0) - break; - } -- dentry = cached_lookup(nd->dentry, &this, 0); -+ dentry = cached_lookup(nd->dentry, &this, 0, it); - if (!dentry) { -- dentry = real_lookup(nd->dentry, &this, 0); -+ dentry = real_lookup(nd->dentry, &this, 0, it); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; -@@ -593,9 +624,9 @@ last_component: - while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry)) - ; - inode = dentry->d_inode; -- if ((lookup_flags & LOOKUP_FOLLOW) -- && inode && inode->i_op && inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op && -+ (inode->i_op->follow_link || inode->i_op->follow_link2)) { -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -609,7 +640,8 @@ last_component: - goto no_inode; - if (lookup_flags & LOOKUP_DIRECTORY) { - err = -ENOTDIR; -- if (!inode->i_op || !inode->i_op->lookup) -+ if (!inode->i_op || -+ (!inode->i_op->lookup && !inode->i_op->lookup2)) - break; - } - goto return_base; -@@ -646,15 +678,28 @@ out_dput: - dput(dentry); - break; - } -+ if (err) -+ intent_release(nd->dentry, it); - path_release(nd); - return_err: - return err; - } - -+int link_path_walk(const char * name, struct nameidata *nd) -+{ -+ return link_path_walk_it(name, nd, NULL); -+} -+ -+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it) -+{ -+ current->total_link_count = 0; -+ return link_path_walk_it(name, nd, it); -+} -+ - int path_walk(const char * name, struct nameidata *nd) - { - current->total_link_count = 0; -- return link_path_walk(name, nd); -+ return link_path_walk_it(name, nd, NULL); - } - - /* SMP-safe */ -@@ -757,7 +802,8 @@ int path_init(const char *name, unsigned - * needs parent already locked. Doesn't follow mounts. - * SMP-safe. - */ --struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, -+ struct lookup_intent *it) - { - struct dentry * dentry; - struct inode *inode; -@@ -780,13 +826,16 @@ struct dentry * lookup_hash(struct qstr - goto out; - } - -- dentry = cached_lookup(base, name, 0); -+ dentry = cached_lookup(base, name, 0, it); - if (!dentry) { - struct dentry *new = d_alloc(base, name); - dentry = ERR_PTR(-ENOMEM); - if (!new) - goto out; - lock_kernel(); -+ if (inode->i_op->lookup2) -+ dentry = inode->i_op->lookup2(inode, new, it); -+ else - dentry = inode->i_op->lookup(inode, new); - unlock_kernel(); - if (!dentry) -@@ -798,6 +847,12 @@ out: - return dentry; - } - -+struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+{ -+ return lookup_hash_it(name, base, NULL); -+} -+ -+ - /* SMP-safe */ - struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) - { -@@ -819,7 +874,7 @@ struct dentry * lookup_one_len(const cha - } - this.hash = end_name_hash(hash); - -- return lookup_hash(&this, base); -+ return lookup_hash_it(&this, base, NULL); - access: - return ERR_PTR(-EACCES); - } -@@ -851,6 +906,23 @@ int __user_walk(const char *name, unsign - return err; - } - -+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it) -+{ -+ char *tmp; -+ int err; -+ -+ tmp = getname(name); -+ err = PTR_ERR(tmp); -+ if (!IS_ERR(tmp)) { -+ err = 0; -+ if (path_init(tmp, flags, nd)) -+ err = path_walk_it(tmp, nd, it); -+ putname(tmp); -+ } -+ return err; -+} -+ - /* - * It's inline, so penalty for filesystems that don't use sticky bit is - * minimal. -@@ -987,7 +1059,8 @@ exit_lock: - * for symlinks (where the permissions are checked later). - * SMP-safe - */ --int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) -+int open_namei_it(const char *pathname, int flag, int mode, -+ struct nameidata *nd, struct lookup_intent *it) - { - int acc_mode, error = 0; - struct inode *inode; -@@ -1002,7 +1075,7 @@ int open_namei(const char * pathname, in - */ - if (!(flag & O_CREAT)) { - if (path_init(pathname, lookup_flags(flag), nd)) -- error = path_walk(pathname, nd); -+ error = path_walk_it(pathname, nd, it); - if (error) - return error; - dentry = nd->dentry; -@@ -1012,6 +1085,10 @@ int open_namei(const char * pathname, in - /* - * Create - we need to know the parent. - */ -+ if (it) { -+ it->it_mode = mode; -+ it->it_op |= IT_CREAT; -+ } - if (path_init(pathname, LOOKUP_PARENT, nd)) - error = path_walk(pathname, nd); - if (error) -@@ -1028,7 +1105,7 @@ int open_namei(const char * pathname, in - - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - - do_last: - error = PTR_ERR(dentry); -@@ -1037,6 +1114,7 @@ do_last: - goto exit; - } - -+ it->it_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { - error = vfs_create(dir->d_inode, dentry, -@@ -1070,7 +1148,8 @@ do_last: - error = -ENOENT; - if (!dentry->d_inode) - goto exit_dput; -- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) -+ if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || -+ dentry->d_inode->i_op->follow_link2)) - goto do_link; - - dput(nd->dentry); -@@ -1156,8 +1235,10 @@ ok: - return 0; - - exit_dput: -+ intent_release(dentry, it); - dput(dentry); - exit: -+ intent_release(nd->dentry, it); - path_release(nd); - return error; - -@@ -1176,7 +1257,12 @@ do_link: - * are done. Procfs-like symlinks just set LAST_BIND. - */ - UPDATE_ATIME(dentry->d_inode); -- error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ error = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (error) -+ intent_release(dentry, it); - dput(dentry); - if (error) - return error; -@@ -1198,13 +1284,20 @@ do_link: - } - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - putname(nd->last.name); - goto do_last; - } - -+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd) -+{ -+ return open_namei_it(pathname, flag, mode, nd, NULL); -+} -+ -+ - /* SMP-safe */ --static struct dentry *lookup_create(struct nameidata *nd, int is_dir) -+static struct dentry *lookup_create(struct nameidata *nd, int is_dir, -+ struct lookup_intent *it) - { - struct dentry *dentry; - -@@ -1212,7 +1305,7 @@ static struct dentry *lookup_create(stru - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - if (IS_ERR(dentry)) - goto fail; - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) -@@ -1258,6 +1351,7 @@ asmlinkage long sys_mknod(const char * f - char * tmp; - struct dentry * dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode }; - - if (S_ISDIR(mode)) - return -EPERM; -@@ -1269,7 +1363,19 @@ asmlinkage long sys_mknod(const char * f - error = path_walk(tmp, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ -+ if (nd.dentry->d_inode->i_op->mknod2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mknod2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ mode, dev); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ -+ dentry = lookup_create(&nd, 0, &it); - error = PTR_ERR(dentry); - - mode &= ~current->fs->umask; -@@ -1287,9 +1393,11 @@ asmlinkage long sys_mknod(const char * f - default: - error = -EINVAL; - } -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+ out2: - path_release(&nd); - out: - putname(tmp); -@@ -1327,6 +1435,7 @@ asmlinkage long sys_mkdir(const char * p - { - int error = 0; - char * tmp; -+ struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode }; - - tmp = getname(pathname); - error = PTR_ERR(tmp); -@@ -1338,14 +1447,26 @@ asmlinkage long sys_mkdir(const char * p - error = path_walk(tmp, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 1); -+ if (nd.dentry->d_inode->i_op->mkdir2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mkdir2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ mode); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ 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); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1426,6 +1547,7 @@ asmlinkage long sys_rmdir(const char * p - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_RMDIR }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1447,11 +1569,21 @@ asmlinkage long sys_rmdir(const char * p - error = -EBUSY; - goto exit1; - } -+ if (nd.dentry->d_inode->i_op->rmdir2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->rmdir2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit1; -+ } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &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); -@@ -1495,6 +1627,7 @@ asmlinkage long sys_unlink(const char * - char * name; - struct dentry *dentry; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_UNLINK }; - - name = getname(pathname); - if(IS_ERR(name)) -@@ -1507,8 +1640,17 @@ asmlinkage long sys_unlink(const char * - error = -EISDIR; - if (nd.last_type != LAST_NORM) - goto exit1; -+ if (nd.dentry->d_inode->i_op->unlink2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->unlink2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit1; -+ } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - /* Why not before? Because we want correct error value */ -@@ -1516,6 +1658,7 @@ asmlinkage long sys_unlink(const char * - goto slashes; - error = vfs_unlink(nd.dentry->d_inode, dentry); - exit2: -+ intent_release(dentry, &it); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -@@ -1562,6 +1705,7 @@ asmlinkage long sys_symlink(const char * - int error = 0; - char * from; - char * to; -+ struct lookup_intent it = { .it_op = IT_SYMLINK }; - - from = getname(oldname); - if(IS_ERR(from)) -@@ -1576,15 +1720,28 @@ asmlinkage long sys_symlink(const char * - error = path_walk(to, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ if (nd.dentry->d_inode->i_op->symlink2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->symlink2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ from); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ 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); -+ out2: - path_release(&nd); --out: -+ out: - putname(to); - } - putname(from); -@@ -1645,6 +1802,7 @@ asmlinkage long sys_link(const char * ol - int error; - char * from; - char * to; -+ struct lookup_intent it = { .it_op = IT_LINK }; - - from = getname(oldname); - if(IS_ERR(from)) -@@ -1657,7 +1815,7 @@ asmlinkage long sys_link(const char * ol - - 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)) -@@ -1667,10 +1825,22 @@ asmlinkage long sys_link(const char * ol - error = -EXDEV; - if (old_nd.mnt != nd.mnt) - goto out_release; -- new_dentry = lookup_create(&nd, 0); -+ if (nd.dentry->d_inode->i_op->link2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->link2(old_nd.dentry->d_inode, -+ nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out_release; -+ } -+ 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); -@@ -1713,7 +1883,8 @@ exit: - * locking]. - */ - int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - struct inode *target; -@@ -1771,6 +1942,7 @@ int vfs_rename_dir(struct inode *old_dir - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - if (target) { - if (!error) - target->i_flags |= S_DEAD; -@@ -1792,7 +1964,8 @@ out_unlock: - } - - int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - -@@ -1823,6 +1996,7 @@ int vfs_rename_other(struct inode *old_d - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - double_up(&old_dir->i_zombie, &new_dir->i_zombie); - if (error) - return error; -@@ -1834,13 +2008,14 @@ int vfs_rename_other(struct inode *old_d - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - if (S_ISDIR(old_dentry->d_inode->i_mode)) -- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); - else -- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); - if (!error) { - if (old_dir == new_dir) - inode_dir_notify(old_dir, DN_RENAME); -@@ -1857,6 +2032,7 @@ static inline int do_rename(const char * - int error = 0; - struct dentry * old_dir, * new_dir; - struct dentry * old_dentry, *new_dentry; -+ struct lookup_intent it = { .it_op = IT_RENAME }; - struct nameidata oldnd, newnd; - - if (path_init(oldname, LOOKUP_PARENT, &oldnd)) -@@ -1883,9 +2059,23 @@ static inline int do_rename(const char * - if (newnd.last_type != LAST_NORM) - goto exit2; - -+ if (old_dir->d_inode->i_op->rename2) { -+ lock_kernel(); -+ error = old_dir->d_inode->i_op->rename2(old_dir->d_inode, -+ new_dir->d_inode, -+ oldnd.last.name, -+ oldnd.last.len, -+ newnd.last.name, -+ newnd.last.len); -+ unlock_kernel(); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit2; -+ } -+ - double_lock(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -1901,18 +2091,21 @@ static inline int do_rename(const char * - if (newnd.last.name[newnd.last.len]) - goto exit4; - } -- new_dentry = lookup_hash(&newnd.last, new_dir); -+ it.it_op = IT_RENAME2; -+ new_dentry = lookup_hash_it(&newnd.last, new_dir, &it); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; - - lock_kernel(); - error = vfs_rename(old_dir->d_inode, old_dentry, -- new_dir->d_inode, new_dentry); -+ new_dir->d_inode, new_dentry, &it); - unlock_kernel(); - -+ intent_release(new_dentry, &it); - dput(new_dentry); - exit4: -+ intent_release(old_dentry, &it); - dput(old_dentry); - exit3: - double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); -@@ -1961,7 +2154,8 @@ out: - } - - static inline int --__vfs_follow_link(struct nameidata *nd, const char *link) -+__vfs_follow_link(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) - { - int res = 0; - char *name; -@@ -1974,7 +2168,7 @@ __vfs_follow_link(struct nameidata *nd, - /* weird __emul_prefix() stuff did it */ - goto out; - } -- res = link_path_walk(link, nd); -+ res = link_path_walk_it(link, nd, it); - out: - if (current->link_count || res || nd->last_type!=LAST_NORM) - return res; -@@ -1996,7 +2190,13 @@ fail: - - int vfs_follow_link(struct nameidata *nd, const char *link) - { -- return __vfs_follow_link(nd, link); -+ return __vfs_follow_link(nd, link, NULL); -+} -+ -+int vfs_follow_link_it(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) -+{ -+ return __vfs_follow_link(nd, link, it); - } - - /* get the link contents into pagecache */ -@@ -2038,7 +2238,7 @@ int page_follow_link(struct dentry *dent - { - struct page *page = NULL; - char *s = page_getlink(dentry, &page); -- int res = __vfs_follow_link(nd, s); -+ int res = __vfs_follow_link(nd, s, NULL); - if (page) { - kunmap(page); - page_cache_release(page); ---- linux-2.4.19/fs/open.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/fs/open.c Sun Jan 19 19:46:42 2003 -@@ -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 @@ static inline long do_sys_truncate(const - struct nameidata nd; - struct inode * inode; - int error; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - - error = -EINVAL; - if (length < 0) /* sorry, but loff_t says... */ - goto out; - -- error = user_path_walk(path, &nd); -+ error = user_path_walk_it(path, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -168,6 +172,7 @@ static inline long do_sys_truncate(const - put_write_access(inode); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -259,8 +264,9 @@ asmlinkage long sys_utime(char * filenam - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -286,6 +292,7 @@ asmlinkage long sys_utime(char * filenam - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -303,8 +310,9 @@ asmlinkage long sys_utimes(char * filena - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - - if (error) - goto out; -@@ -331,6 +339,7 @@ asmlinkage long sys_utimes(char * filena - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -347,6 +356,7 @@ asmlinkage long sys_access(const char * - int old_fsuid, old_fsgid; - kernel_cap_t old_cap; - int res; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ - return -EINVAL; -@@ -364,13 +374,14 @@ asmlinkage long sys_access(const char * - else - current->cap_effective = current->cap_permitted; - -- res = user_path_walk(filename, &nd); -+ res = user_path_walk_it(filename, &nd, &it); - if (!res) { - res = permission(nd.dentry->d_inode, mode); - /* SuS v2 requires we report a read only fs too */ - if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) - && !special_file(nd.dentry->d_inode->i_mode)) - res = -EROFS; -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - -@@ -386,6 +397,7 @@ asmlinkage long sys_chdir(const char * f - int error; - struct nameidata nd; - char *name; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - name = getname(filename); - error = PTR_ERR(name); -@@ -394,7 +406,7 @@ asmlinkage long sys_chdir(const char * f - - 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; -@@ -406,6 +418,7 @@ asmlinkage long sys_chdir(const char * f - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -446,6 +459,7 @@ asmlinkage long sys_chroot(const char * - int error; - struct nameidata nd; - char *name; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - name = getname(filename); - error = PTR_ERR(name); -@@ -454,7 +468,7 @@ asmlinkage long sys_chroot(const char * - - 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; -@@ -471,6 +485,7 @@ asmlinkage long sys_chroot(const char * - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -515,8 +530,9 @@ asmlinkage long sys_chmod(const char * f - struct inode * inode; - int error; - struct iattr newattrs; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -536,6 +552,7 @@ asmlinkage long sys_chmod(const char * f - error = notify_change(nd.dentry, &newattrs); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -605,10 +622,12 @@ asmlinkage long sys_chown(const char * f - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = chown_common(nd.dentry, user, group); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -618,10 +637,12 @@ asmlinkage long sys_lchown(const char * - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = chown_common(nd.dentry, user, group); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -655,10 +676,16 @@ asmlinkage long sys_fchown(unsigned int - * for the internal routines (ie open_namei()/follow_link() etc). 00 is - * used by symlinks. - */ -+extern int open_namei_it(const char *filename, int namei_flags, int mode, -+ struct nameidata *nd, struct lookup_intent *it); -+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it); -+ - struct file *filp_open(const char * filename, int flags, int mode) - { - int namei_flags, error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_OPEN }; - - namei_flags = flags; - if ((namei_flags+1) & O_ACCMODE) -@@ -666,14 +693,15 @@ struct file *filp_open(const char * file - if (namei_flags & O_TRUNC) - namei_flags |= 2; - -- error = open_namei(filename, namei_flags, mode, &nd); -- if (!error) -- return dentry_open(nd.dentry, nd.mnt, flags); -+ error = open_namei_it(filename, namei_flags, mode, &nd, &it); -+ if (error) -+ return ERR_PTR(error); - -- return ERR_PTR(error); -+ return dentry_open_it(nd.dentry, nd.mnt, flags, &it); - } - --struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it) - { - struct file * f; - struct inode *inode; -@@ -716,6 +744,7 @@ struct file *dentry_open(struct dentry * - } - f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); - -+ intent_release(dentry, it); - return f; - - cleanup_all: -@@ -730,11 +759,17 @@ cleanup_all: - cleanup_file: - put_filp(f); - cleanup_dentry: -+ intent_release(dentry, it); - dput(dentry); - mntput(mnt); - return ERR_PTR(error); - } - -+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+{ -+ return dentry_open_it(dentry, mnt, flags, NULL); -+} -+ - /* - * Find an empty file descriptor entry, and mark it busy. - */ ---- linux-2.4.19/fs/stat.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/fs/stat.c Sun Jan 19 19:46:42 2003 -@@ -13,6 +13,7 @@ - - #include - -+extern void intent_release(struct dentry *de, struct lookup_intent *it); - /* - * Revalidate the inode. This is required for proper NFS attribute caching. - */ -@@ -135,13 +136,15 @@ static int cp_new_stat(struct inode * in - asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -151,13 +154,15 @@ asmlinkage long sys_stat(char * filename - asmlinkage long sys_newstat(char * filename, struct stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -172,13 +177,15 @@ asmlinkage long sys_newstat(char * filen - asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -189,13 +196,15 @@ asmlinkage long sys_lstat(char * filenam - asmlinkage long sys_newlstat(char * filename, struct stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -247,20 +256,21 @@ asmlinkage long sys_readlink(const char - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_READLINK }; - - if (bufsiz <= 0) - return -EINVAL; - -- error = user_path_walk_link(path, &nd); -+ error = user_path_walk_link_it(path, &nd, &it); - if (!error) { - struct inode * inode = nd.dentry->d_inode; -- - error = -EINVAL; - if (inode->i_op && inode->i_op->readlink && - !(error = do_revalidate(nd.dentry))) { - UPDATE_ATIME(inode); - error = inode->i_op->readlink(nd.dentry, buf, bufsiz); - } -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -333,12 +343,14 @@ asmlinkage long sys_stat64(char * filena - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -348,12 +360,14 @@ asmlinkage long sys_lstat64(char * filen - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; ---- linux-2.4.19/mm/slab.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003 -+++ linux-2.4.19-root/mm/slab.c Sun Jan 19 19:46:42 2003 -@@ -1207,6 +1207,59 @@ failed: - * Called with the cache-lock held. - */ - -+extern struct page *check_get_page(unsigned long kaddr); -+struct page *page_mem_map(struct page *page); -+static int kmem_check_cache_obj (kmem_cache_t * cachep, -+ slab_t *slabp, void * objp) -+{ -+ int i; -+ unsigned int objnr; -+ -+#if DEBUG -+ if (cachep->flags & SLAB_RED_ZONE) { -+ objp -= BYTES_PER_WORD; -+ if ( *(unsigned long *)objp != RED_MAGIC2) -+ /* Either write before start, or a double free. */ -+ return 0; -+ if (*(unsigned long *)(objp+cachep->objsize - -+ BYTES_PER_WORD) != RED_MAGIC2) -+ /* Either write past end, or a double free. */ -+ return 0; -+ } -+#endif -+ -+ objnr = (objp-slabp->s_mem)/cachep->objsize; -+ if (objnr >= cachep->num) -+ return 0; -+ if (objp != slabp->s_mem + objnr*cachep->objsize) -+ return 0; -+ -+ /* Check slab's freelist to see if this obj is there. */ -+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { -+ if (i == objnr) -+ return 0; -+ } -+ return 1; -+} -+ -+ -+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) -+{ -+ struct page *page = check_get_page((unsigned long)objp); -+ -+ if (!VALID_PAGE(page)) -+ return 0; -+ -+ if (!PageSlab(page)) -+ return 0; -+ -+ /* XXX check for freed slab objects ? */ -+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) -+ return 0; -+ -+ return (cachep == GET_PAGE_CACHE(page)); -+} -+ - #if DEBUG - static int kmem_extra_free_checks (kmem_cache_t * cachep, - slab_t *slabp, void * objp) - -_ diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.18-18.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.18-18.patch deleted file mode 100644 index 5c1f090..0000000 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.18-18.patch +++ /dev/null @@ -1,1448 +0,0 @@ - fs/dcache.c | 20 ++ - fs/exec.c | 18 +- - fs/namei.c | 338 ++++++++++++++++++++++++++++++++++++++++--------- - fs/nfsd/vfs.c | 2 - fs/open.c | 120 +++++++++++++++-- - fs/stat.c | 8 - - include/linux/dcache.h | 28 ++++ - include/linux/fs.h | 27 +++ - kernel/ksyms.c | 1 - 9 files changed, 478 insertions(+), 84 deletions(-) - ---- linux-2.4.18-18.8.0-l12/fs/dcache.c~vfs_intent-2.4.18-18 Wed Feb 26 16:54:17 2003 -+++ linux-2.4.18-18.8.0-l12-phil/fs/dcache.c Wed Feb 26 17:31:36 2003 -@@ -186,6 +186,13 @@ int d_invalidate(struct dentry * dentry) - spin_unlock(&dcache_lock); - return 0; - } -+ -+ /* network invalidation by Lustre */ -+ if (dentry->d_flags & DCACHE_LUSTRE_INVALID) { -+ spin_unlock(&dcache_lock); -+ return 0; -+ } -+ - /* - * Check whether to do a partial shrink_dcache - * to get rid of unused child entries. -@@ -645,6 +652,7 @@ struct dentry * d_alloc(struct dentry * - dentry->d_fsdata = NULL; - dentry->d_extra_attributes = NULL; - dentry->d_mounted = 0; -+ dentry->d_it = NULL; - INIT_LIST_HEAD(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); -@@ -859,13 +867,19 @@ void d_delete(struct dentry * dentry) - * Adds a dentry to the hash according to its name. - */ - --void d_rehash(struct dentry * entry) -+void __d_rehash(struct dentry * entry, int lock) - { - struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash); - if (!list_empty(&entry->d_hash)) BUG(); -- spin_lock(&dcache_lock); -+ if (lock) spin_lock(&dcache_lock); - list_add(&entry->d_hash, list); -- spin_unlock(&dcache_lock); -+ if (lock) spin_unlock(&dcache_lock); -+} -+EXPORT_SYMBOL(__d_rehash); -+ -+void d_rehash(struct dentry * entry) -+{ -+ __d_rehash(entry, 1); - } - - #define do_switch(x,y) do { \ ---- linux-2.4.18-18.8.0-l12/fs/namei.c~vfs_intent-2.4.18-18 Wed Feb 26 16:54:17 2003 -+++ linux-2.4.18-18.8.0-l12-phil/fs/namei.c Wed Feb 26 16:54:17 2003 -@@ -94,6 +94,13 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct dentry *de, struct lookup_intent *it) -+{ -+ if (it && de->d_op && de->d_op->d_intent_release) -+ de->d_op->d_intent_release(de, it); -+ -+} -+ - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the - * kernel data space before using them.. -@@ -260,10 +267,19 @@ void path_release(struct nameidata *nd) - * Internal lookup() using the new generic dcache. - * SMP-safe - */ --static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * dentry = d_lookup(parent, name); - -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { -+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -281,11 +297,14 @@ static struct dentry * cached_lookup(str - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; - -+again: -+ - down(&dir->i_sem); - /* - * First re-do the cached lookup just in case it was created -@@ -300,6 +319,9 @@ static struct dentry * real_lookup(struc - result = ERR_PTR(-ENOMEM); - if (dentry) { - lock_kernel(); -+ if (dir->i_op->lookup2) -+ result = dir->i_op->lookup2(dir, dentry, it); -+ else - result = dir->i_op->lookup(dir, dentry); - unlock_kernel(); - if (result) -@@ -321,6 +343,12 @@ static struct dentry * real_lookup(struc - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate2) { -+ if (!result->d_op->d_revalidate2(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ goto again; -+ } - } - return result; - } -@@ -334,7 +362,8 @@ int max_recursive_link = 5; - * Without that kind of total limit, nasty chains of consecutive - * symlinks can cause almost arbitrarily long lookups. - */ --static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) -+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, -+ struct lookup_intent *it) - { - int err; - if (current->link_count >= max_recursive_link) -@@ -348,10 +377,14 @@ static inline int do_follow_link(struct - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -- err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -+ intent_release(dentry, it); - path_release(nd); - return -ELOOP; - } -@@ -381,15 +414,26 @@ int follow_up(struct vfsmount **mnt, str - return __follow_up(mnt, dentry); - } - --static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry) -+static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry, -+ struct lookup_intent *it) - { - struct vfsmount *mounted; - - spin_lock(&dcache_lock); - mounted = lookup_mnt(*mnt, *dentry); - if (mounted) { -+ int opc = 0, mode = 0; - *mnt = mntget(mounted); - spin_unlock(&dcache_lock); -+ if (it) { -+ opc = it->it_op; -+ mode = it->it_mode; -+ } -+ intent_release(*dentry, it); -+ if (it) { -+ it->it_op = opc; -+ it->it_mode = mode; -+ } - dput(*dentry); - mntput(mounted->mnt_parent); - *dentry = dget(mounted->mnt_root); -@@ -401,7 +445,7 @@ static inline int __follow_down(struct v - - int follow_down(struct vfsmount **mnt, struct dentry **dentry) - { -- return __follow_down(mnt,dentry); -+ return __follow_down(mnt,dentry,NULL); - } - - static inline void follow_dotdot(struct nameidata *nd) -@@ -437,7 +481,7 @@ static inline void follow_dotdot(struct - mntput(nd->mnt); - nd->mnt = parent; - } -- while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry)) -+ while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry, NULL)) - ; - } - -@@ -449,7 +493,8 @@ static inline void follow_dotdot(struct - * - * We expect 'base' to be positive and a directory. - */ --int link_path_walk(const char * name, struct nameidata *nd) -+int link_path_walk_it(const char *name, struct nameidata *nd, -+ struct lookup_intent *it) - { - struct dentry *dentry; - struct inode *inode; -@@ -526,18 +571,18 @@ int link_path_walk(const char * name, st - break; - } - /* This does the actual lookups.. */ -- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - if (!dentry) { - err = -EWOULDBLOCKIO; - if (atomic) - break; -- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; - } - /* Check mountpoints.. */ -- while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry)) -+ while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL)) - ; - - err = -ENOENT; -@@ -548,8 +593,8 @@ int link_path_walk(const char * name, st - if (!inode->i_op) - goto out_dput; - -- if (inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ if (inode->i_op->follow_link || inode->i_op->follow_link2) { -+ err = do_follow_link(dentry, nd, NULL); - dput(dentry); - if (err) - goto return_err; -@@ -565,7 +610,7 @@ int link_path_walk(const char * name, st - nd->dentry = dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup2) - break; - continue; - /* here ends the main loop */ -@@ -592,22 +637,23 @@ last_component: - if (err < 0) - break; - } -- dentry = cached_lookup(nd->dentry, &this, 0); -+ dentry = cached_lookup(nd->dentry, &this, 0, it); - if (!dentry) { - err = -EWOULDBLOCKIO; - if (atomic) - break; -- dentry = real_lookup(nd->dentry, &this, 0); -+ dentry = real_lookup(nd->dentry, &this, 0, it); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; - } -- while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry)) -+ while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, it)) - ; - inode = dentry->d_inode; - if ((lookup_flags & LOOKUP_FOLLOW) -- && inode && inode->i_op && inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ && inode && inode->i_op && -+ (inode->i_op->follow_link || inode->i_op->follow_link2)) { -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -621,7 +667,8 @@ last_component: - goto no_inode; - if (lookup_flags & LOOKUP_DIRECTORY) { - err = -ENOTDIR; -- if (!inode->i_op || !inode->i_op->lookup) -+ if (!inode->i_op || -+ (!inode->i_op->lookup && !inode->i_op->lookup2)) - break; - } - goto return_base; -@@ -658,15 +705,28 @@ out_dput: - dput(dentry); - break; - } -+ if (err) -+ intent_release(nd->dentry, it); - path_release(nd); - return_err: - return err; - } - -+int link_path_walk(const char * name, struct nameidata *nd) -+{ -+ return link_path_walk_it(name, nd, NULL); -+} -+ -+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it) -+{ -+ current->total_link_count = 0; -+ return link_path_walk_it(name, nd, it); -+} -+ - int path_walk(const char * name, struct nameidata *nd) - { - current->total_link_count = 0; -- return link_path_walk(name, nd); -+ return link_path_walk_it(name, nd, NULL); - } - - /* SMP-safe */ -@@ -751,6 +811,17 @@ walk_init_root(const char *name, struct - } - - /* SMP-safe */ -+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it) -+{ -+ int error = 0; -+ if (path_init(path, flags, nd)) -+ error = path_walk_it(path, nd, it); -+ return error; -+} -+ -+ -+/* SMP-safe */ - int path_lookup(const char *path, unsigned flags, struct nameidata *nd) - { - int error = 0; -@@ -779,7 +850,8 @@ int path_init(const char *name, unsigned - * needs parent already locked. Doesn't follow mounts. - * SMP-safe. - */ --struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, -+ struct lookup_intent *it) - { - struct dentry * dentry; - struct inode *inode; -@@ -802,13 +874,16 @@ struct dentry * lookup_hash(struct qstr - goto out; - } - -- dentry = cached_lookup(base, name, 0); -+ dentry = cached_lookup(base, name, 0, it); - if (!dentry) { - struct dentry *new = d_alloc(base, name); - dentry = ERR_PTR(-ENOMEM); - if (!new) - goto out; - lock_kernel(); -+ if (inode->i_op->lookup2) -+ dentry = inode->i_op->lookup2(inode, new, it); -+ else - dentry = inode->i_op->lookup(inode, new); - unlock_kernel(); - if (!dentry) -@@ -820,6 +895,12 @@ out: - return dentry; - } - -+struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+{ -+ return lookup_hash_it(name, base, NULL); -+} -+ -+ - /* SMP-safe */ - struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) - { -@@ -841,7 +922,7 @@ struct dentry * lookup_one_len(const cha - } - this.hash = end_name_hash(hash); - -- return lookup_hash(&this, base); -+ return lookup_hash_it(&this, base, NULL); - access: - return ERR_PTR(-EACCES); - } -@@ -872,6 +953,23 @@ int __user_walk(const char *name, unsign - return err; - } - -+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it) -+{ -+ char *tmp; -+ int err; -+ -+ tmp = getname(name); -+ err = PTR_ERR(tmp); -+ if (!IS_ERR(tmp)) { -+ err = 0; -+ if (path_init(tmp, flags, nd)) -+ err = path_walk_it(tmp, nd, it); -+ putname(tmp); -+ } -+ return err; -+} -+ - /* - * It's inline, so penalty for filesystems that don't use sticky bit is - * minimal. -@@ -1045,14 +1143,17 @@ int may_open(struct nameidata *nd, int a - return get_lease(inode, flag); - } - -+extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it); -+ - struct file *filp_open(const char * pathname, int open_flags, int mode) - { - int acc_mode, error = 0; -- struct inode *inode; - struct dentry *dentry; - struct dentry *dir; - int flag = open_flags; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = open_flags }; - int count = 0; - - if ((flag+1) & O_ACCMODE) -@@ -1066,7 +1167,7 @@ struct file *filp_open(const char * path - * 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 ERR_PTR(error); - dentry = nd.dentry; -@@ -1076,6 +1177,8 @@ struct file *filp_open(const char * path - /* - * Create - we need to know the parent. - */ -+ it.it_mode = mode; -+ it.it_op |= IT_CREAT; - error = path_lookup(pathname, LOOKUP_PARENT, &nd); - if (error) - return ERR_PTR(error); -@@ -1091,7 +1194,7 @@ struct file *filp_open(const char * path - - 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); -@@ -1100,6 +1203,7 @@ do_last: - goto exit; - } - -+ it.it_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { - error = vfs_create(dir->d_inode, dentry, -@@ -1129,12 +1233,13 @@ do_last: - error = -ELOOP; - if (flag & O_NOFOLLOW) - goto exit_dput; -- while (__follow_down(&nd.mnt,&dentry) && d_mountpoint(dentry)); -+ while (__follow_down(&nd.mnt,&dentry,&it) && d_mountpoint(dentry)); - } - error = -ENOENT; - if (!dentry->d_inode) - goto exit_dput; -- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) -+ if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || -+ dentry->d_inode->i_op->follow_link2)) - goto do_link; - - dput(nd.dentry); -@@ -1149,11 +1254,13 @@ ok: - if (!S_ISREG(nd.dentry->d_inode->i_mode)) - open_flags &= ~O_TRUNC; - -- return dentry_open(nd.dentry, nd.mnt, open_flags); -+ return dentry_open_it(nd.dentry, nd.mnt, open_flags, &it); - - exit_dput: -+ intent_release(dentry, &it); - dput(dentry); - exit: -+ intent_release(nd.dentry, &it); - path_release(&nd); - return ERR_PTR(error); - -@@ -1172,10 +1279,15 @@ do_link: - * are done. Procfs-like symlinks just set LAST_BIND. - */ - UPDATE_ATIME(dentry->d_inode); -- error = dentry->d_inode->i_op->follow_link(dentry, &nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ error = dentry->d_inode->i_op->follow_link2(dentry, &nd, &it); -+ else -+ error = dentry->d_inode->i_op->follow_link(dentry, &nd); -+ if (error) -+ intent_release(dentry, &it); - dput(dentry); - if (error) -- return error; -+ return ERR_PTR(error); - if (nd.last_type == LAST_BIND) { - dentry = nd.dentry; - goto ok; -@@ -1194,13 +1306,15 @@ do_link: - } - dir = nd.dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); - putname(nd.last.name); - goto do_last; - } - -+ - /* 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; - -@@ -1208,7 +1322,7 @@ static struct dentry *lookup_create(stru - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - if (IS_ERR(dentry)) - goto fail; - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) -@@ -1264,7 +1378,19 @@ asmlinkage long sys_mknod(const char * f - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ -+ if (nd.dentry->d_inode->i_op->mknod2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mknod2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ mode, dev); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ -+ dentry = lookup_create(&nd, 0, NULL); - error = PTR_ERR(dentry); - - mode &= ~current->fs->umask; -@@ -1285,6 +1411,7 @@ asmlinkage long sys_mknod(const char * f - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1332,7 +1459,17 @@ asmlinkage long sys_mkdir(const char * p - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 1); -+ if (nd.dentry->d_inode->i_op->mkdir2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mkdir2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ mode); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ dentry = lookup_create(&nd, 1, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_mkdir(nd.dentry->d_inode, dentry, -@@ -1340,6 +1477,7 @@ asmlinkage long sys_mkdir(const char * p - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1440,8 +1578,33 @@ asmlinkage long sys_rmdir(const char * p - error = -EBUSY; - goto exit1; - } -+ if (nd.dentry->d_inode->i_op->rmdir2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ struct dentry *last; -+ -+ down(&nd.dentry->d_inode->i_sem); -+ last = lookup_hash_it(&nd.last, nd.dentry, NULL); -+ up(&nd.dentry->d_inode->i_sem); -+ if (IS_ERR(last)) { -+ error = PTR_ERR(last); -+ goto exit1; -+ } -+ if (d_mountpoint(last)) { -+ dput(last); -+ error = -EBUSY; -+ goto exit1; -+ } -+ dput(last); -+ -+ error = op->rmdir2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit1; -+ } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); -@@ -1499,8 +1662,17 @@ asmlinkage long sys_unlink(const char * - error = -EISDIR; - if (nd.last_type != LAST_NORM) - goto exit1; -+ if (nd.dentry->d_inode->i_op->unlink2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->unlink2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit1; -+ } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - /* Why not before? Because we want correct error value */ -@@ -1567,15 +1739,26 @@ asmlinkage long sys_symlink(const char * - error = path_lookup(to, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ if (nd.dentry->d_inode->i_op->symlink2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->symlink2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ from); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ dentry = lookup_create(&nd, 0, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_symlink(nd.dentry->d_inode, dentry, from); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+ out2: - path_release(&nd); --out: -+ out: - putname(to); - } - putname(from); -@@ -1642,7 +1825,7 @@ asmlinkage long sys_link(const char * ol - struct dentry *new_dentry; - struct nameidata nd, old_nd; - -- error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd); -+ error = __user_walk_it(oldname, LOOKUP_POSITIVE, &old_nd, NULL); - if (error) - goto exit; - error = path_lookup(to, LOOKUP_PARENT, &nd); -@@ -1651,7 +1834,17 @@ asmlinkage long sys_link(const char * ol - error = -EXDEV; - if (old_nd.mnt != nd.mnt) - goto out_release; -- new_dentry = lookup_create(&nd, 0); -+ if (nd.dentry->d_inode->i_op->link2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->link2(old_nd.dentry->d_inode, -+ nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out_release; -+ } -+ new_dentry = lookup_create(&nd, 0, NULL); - error = PTR_ERR(new_dentry); - if (!IS_ERR(new_dentry)) { - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); -@@ -1695,7 +1888,8 @@ exit: - * locking]. - */ - int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - struct inode *target; -@@ -1753,6 +1947,7 @@ int vfs_rename_dir(struct inode *old_dir - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - if (target) { - if (!error) - target->i_flags |= S_DEAD; -@@ -1774,7 +1969,8 @@ out_unlock: - } - - int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - -@@ -1805,6 +2001,7 @@ int vfs_rename_other(struct inode *old_d - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - double_up(&old_dir->i_zombie, &new_dir->i_zombie); - if (error) - return error; -@@ -1816,13 +2013,14 @@ int vfs_rename_other(struct inode *old_d - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - if (S_ISDIR(old_dentry->d_inode->i_mode)) -- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); - else -- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); - if (!error) { - if (old_dir == new_dir) - inode_dir_notify(old_dir, DN_RENAME); -@@ -1864,7 +2062,7 @@ static inline int do_rename(const char * - - double_lock(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -1880,16 +2078,37 @@ static inline int do_rename(const char * - if (newnd.last.name[newnd.last.len]) - goto exit4; - } -- new_dentry = lookup_hash(&newnd.last, new_dir); -+ new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; - -+ if (old_dir->d_inode->i_op->rename2) { -+ lock_kernel(); -+ /* don't rename mount point. mds will take care of -+ * the rest sanity checking */ -+ if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) { -+ error = -EBUSY; -+ goto exit5; -+ } -+ -+ error = old_dir->d_inode->i_op->rename2(old_dir->d_inode, -+ new_dir->d_inode, -+ oldnd.last.name, -+ oldnd.last.len, -+ newnd.last.name, -+ newnd.last.len); -+ unlock_kernel(); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit5; -+ } -+ - lock_kernel(); - error = vfs_rename(old_dir->d_inode, old_dentry, -- new_dir->d_inode, new_dentry); -+ new_dir->d_inode, new_dentry, NULL); - unlock_kernel(); -- -+exit5: - dput(new_dentry); - exit4: - dput(old_dentry); -@@ -1940,7 +2159,8 @@ out: - } - - static inline int --__vfs_follow_link(struct nameidata *nd, const char *link) -+__vfs_follow_link(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) - { - int res = 0; - char *name; -@@ -1953,7 +2173,7 @@ __vfs_follow_link(struct nameidata *nd, - /* weird __emul_prefix() stuff did it */ - goto out; - } -- res = link_path_walk(link, nd); -+ res = link_path_walk_it(link, nd, it); - out: - if (current->link_count || res || nd->last_type!=LAST_NORM) - return res; -@@ -1975,7 +2195,13 @@ fail: - - int vfs_follow_link(struct nameidata *nd, const char *link) - { -- return __vfs_follow_link(nd, link); -+ return __vfs_follow_link(nd, link, NULL); -+} -+ -+int vfs_follow_link_it(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) -+{ -+ return __vfs_follow_link(nd, link, it); - } - - /* get the link contents into pagecache */ -@@ -2017,7 +2243,7 @@ int page_follow_link(struct dentry *dent - { - struct page *page = NULL; - char *s = page_getlink(dentry, &page); -- int res = __vfs_follow_link(nd, s); -+ int res = __vfs_follow_link(nd, s, NULL); - if (page) { - kunmap(page); - page_cache_release(page); ---- linux-2.4.18-18.8.0-l12/fs/nfsd/vfs.c~vfs_intent-2.4.18-18 Wed Feb 26 16:54:17 2003 -+++ linux-2.4.18-18.8.0-l12-phil/fs/nfsd/vfs.c Wed Feb 26 16:54:17 2003 -@@ -1298,7 +1298,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); - unlock_kernel(); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); ---- linux-2.4.18-18.8.0-l12/fs/open.c~vfs_intent-2.4.18-18 Wed Feb 26 16:54:17 2003 -+++ linux-2.4.18-18.8.0-l12-phil/fs/open.c Wed Feb 26 16:54:17 2003 -@@ -19,6 +19,8 @@ - #include - - #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) -+extern int path_walk_it(const char *name, struct nameidata *nd, -+ struct lookup_intent *it); - - int vfs_statfs(struct super_block *sb, struct statfs *buf) - { -@@ -95,9 +97,10 @@ void fd_install(unsigned int fd, struct - write_unlock(&files->file_lock); - } - --int do_truncate(struct dentry *dentry, loff_t length) -+int do_truncate(struct dentry *dentry, loff_t length, int called_from_open) - { - struct inode *inode = dentry->d_inode; -+ struct inode_operations *op = dentry->d_inode->i_op; - int error; - struct iattr newattrs; - -@@ -108,7 +111,14 @@ int do_truncate(struct dentry *dentry, l - down(&inode->i_sem); - newattrs.ia_size = length; - newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; -- error = notify_change(dentry, &newattrs); -+ if (called_from_open) -+ newattrs.ia_valid |= ATTR_FROM_OPEN; -+ if (op->setattr_raw) { -+ newattrs.ia_valid |= ATTR_RAW; -+ newattrs.ia_ctime = CURRENT_TIME; -+ error = op->setattr_raw(inode, &newattrs); -+ } else -+ error = notify_change(dentry, &newattrs); - up(&inode->i_sem); - return error; - } -@@ -118,12 +128,13 @@ static inline long do_sys_truncate(const - struct nameidata nd; - struct inode * inode; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - error = -EINVAL; - if (length < 0) /* sorry, but loff_t says... */ - goto out; - -- error = user_path_walk(path, &nd); -+ error = user_path_walk_it(path, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -163,11 +174,13 @@ static inline long do_sys_truncate(const - error = locks_verify_truncate(inode, NULL, length); - if (!error) { - DQUOT_INIT(inode); -- error = do_truncate(nd.dentry, length); -+ intent_release(nd.dentry, &it); -+ error = do_truncate(nd.dentry, length, 0); - } - put_write_access(inode); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -215,7 +228,7 @@ static inline long do_sys_ftruncate(unsi - - error = locks_verify_truncate(inode, file, length); - if (!error) -- error = do_truncate(dentry, length); -+ error = do_truncate(dentry, length, 0); - out_putf: - fput(file); - out: -@@ -260,11 +273,13 @@ asmlinkage long sys_utime(char * filenam - struct inode * inode; - struct iattr newattrs; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, NULL); - if (error) - goto out; - inode = nd.dentry->d_inode; - -+ /* this is safe without a Lustre lock because it only depends -+ on the super block */ - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; -@@ -279,11 +294,29 @@ asmlinkage long sys_utime(char * filenam - goto dput_and_out; - - newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; -- } else { -+ } -+ -+ if (inode->i_op->setattr_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ -+ newattrs.ia_valid |= ATTR_RAW; -+ error = op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto dput_and_out; -+ } -+ -+ error = -EROFS; -+ if (IS_RDONLY(inode)) -+ goto dput_and_out; -+ -+ error = -EPERM; -+ if (!times) { - if (current->fsuid != inode->i_uid && - (error = permission(inode,MAY_WRITE)) != 0) - goto dput_and_out; - } -+ - error = notify_change(nd.dentry, &newattrs); - dput_and_out: - path_release(&nd); -@@ -304,12 +337,14 @@ asmlinkage long sys_utimes(char * filena - struct inode * inode; - struct iattr newattrs; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, NULL); - - if (error) - goto out; - inode = nd.dentry->d_inode; - -+ /* this is safe without a Lustre lock because it only depends -+ on the super block */ - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; -@@ -324,7 +359,20 @@ asmlinkage long sys_utimes(char * filena - newattrs.ia_atime = times[0].tv_sec; - newattrs.ia_mtime = times[1].tv_sec; - newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; -- } else { -+ } -+ -+ if (inode->i_op->setattr_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ -+ newattrs.ia_valid |= ATTR_RAW; -+ error = op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto dput_and_out; -+ } -+ -+ error = -EPERM; -+ if (!utimes) { - if (current->fsuid != inode->i_uid && - (error = permission(inode,MAY_WRITE)) != 0) - goto dput_and_out; -@@ -347,6 +395,7 @@ asmlinkage long sys_access(const char * - int old_fsuid, old_fsgid; - kernel_cap_t old_cap; - int res; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ - return -EINVAL; -@@ -364,13 +413,14 @@ asmlinkage long sys_access(const char * - else - current->cap_effective = current->cap_permitted; - -- res = user_path_walk(filename, &nd); -+ res = user_path_walk_it(filename, &nd, &it); - if (!res) { - res = permission(nd.dentry->d_inode, mode); - /* SuS v2 requires we report a read only fs too */ - if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) - && !special_file(nd.dentry->d_inode->i_mode)) - res = -EROFS; -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - -@@ -385,8 +435,11 @@ asmlinkage long sys_chdir(const char * f - { - int error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd); -+ error = __user_walk_it(filename, -+ LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, -+ &nd, &it); - if (error) - goto out; - -@@ -397,6 +450,7 @@ asmlinkage long sys_chdir(const char * f - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -436,9 +490,10 @@ asmlinkage long sys_chroot(const char * - { - int error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -- LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); -+ error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -+ LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it); - if (error) - goto out; - -@@ -454,6 +509,7 @@ asmlinkage long sys_chroot(const char * - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -508,6 +564,18 @@ asmlinkage long sys_chmod(const char * f - if (IS_RDONLY(inode)) - goto dput_and_out; - -+ if (inode->i_op->setattr_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ -+ newattrs.ia_mode = mode; -+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -+ newattrs.ia_valid |= ATTR_RAW; -+ error = op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto dput_and_out; -+ } -+ - error = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto dput_and_out; -@@ -538,6 +606,20 @@ static int chown_common(struct dentry * - error = -EROFS; - if (IS_RDONLY(inode)) - goto out; -+ -+ if (inode->i_op->setattr_raw) { -+ struct inode_operations *op = dentry->d_inode->i_op; -+ -+ newattrs.ia_uid = user; -+ newattrs.ia_gid = group; -+ newattrs.ia_valid = ATTR_UID | ATTR_GID; -+ newattrs.ia_valid |= ATTR_RAW; -+ error = op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ return error; -+ } -+ - error = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto out; -@@ -628,7 +710,8 @@ extern ssize_t do_readahead(struct file - /* 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; -@@ -649,7 +732,7 @@ struct file *dentry_open(struct dentry * - error = locks_verify_locked(inode); - if (!error) { - DQUOT_INIT(inode); -- error = do_truncate(dentry, 0); -+ error = do_truncate(dentry, 0, 1); - } - if (error || !(f->f_mode & FMODE_WRITE)) - put_write_access(inode); -@@ -693,6 +776,7 @@ struct file *dentry_open(struct dentry * - do_readahead(f, 0, (48 * 1024) >> PAGE_SHIFT); - - -+ intent_release(dentry, it); - return f; - - cleanup_all: -@@ -707,11 +791,17 @@ cleanup_all: - cleanup_file: - put_filp(f); - cleanup_dentry: -+ intent_release(dentry, it); - dput(dentry); - mntput(mnt); - return ERR_PTR(error); - } - -+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+{ -+ return dentry_open_it(dentry, mnt, flags, NULL); -+} -+ - /* - * Find an empty file descriptor entry, and mark it busy. - */ ---- linux-2.4.18-18.8.0-l12/fs/stat.c~vfs_intent-2.4.18-18 Wed Feb 26 16:54:17 2003 -+++ linux-2.4.18-18.8.0-l12-phil/fs/stat.c Wed Feb 26 16:54:17 2003 -@@ -104,10 +104,12 @@ int vfs_stat(char *name, struct kstat *s - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk(name, &nd); -+ error = user_path_walk_it(name, &nd, &it); - if (!error) { - error = do_getattr(nd.mnt, nd.dentry, stat); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -117,10 +119,12 @@ int vfs_lstat(char *name, struct kstat * - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk_link(name, &nd); -+ error = user_path_walk_link_it(name, &nd, &it); - if (!error) { - error = do_getattr(nd.mnt, nd.dentry, stat); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; ---- linux-2.4.18-18.8.0-l12/fs/exec.c~vfs_intent-2.4.18-18 Wed Feb 26 16:54:17 2003 -+++ linux-2.4.18-18.8.0-l12-phil/fs/exec.c Wed Feb 26 16:54:17 2003 -@@ -103,13 +103,18 @@ static inline void put_binfmt(struct lin - * - * Also note that we take the address to load from from the file itself. - */ -+extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it); -+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it); - asmlinkage long sys_uselib(const char * library) - { - struct file * file; - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY }; - -- error = user_path_walk(library, &nd); -+ error = user_path_walk_it(library, &nd, &it); - if (error) - goto out; - -@@ -121,7 +126,8 @@ asmlinkage long sys_uselib(const char * - if (error) - goto exit; - -- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); -+ file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it); -+ intent_release(nd.dentry, &it); - error = PTR_ERR(file); - if (IS_ERR(file)) - goto out; -@@ -350,8 +356,9 @@ struct file *open_exec(const char *name) - struct inode *inode; - struct file *file; - int err = 0; -+ struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY }; - -- err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd); -+ err = path_lookup_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it); - file = ERR_PTR(err); - if (!err) { - inode = nd.dentry->d_inode; -@@ -363,7 +370,8 @@ struct file *open_exec(const char *name) - err = -EACCES; - file = ERR_PTR(err); - if (!err) { -- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); -+ file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it); -+ intent_release(nd.dentry, &it); - if (!IS_ERR(file)) { - err = deny_write_access(file); - if (err) { -@@ -976,7 +984,7 @@ int do_coredump(long signr, struct pt_re - goto close_fail; - if (!file->f_op->write) - goto close_fail; -- if (do_truncate(file->f_dentry, 0) != 0) -+ if (do_truncate(file->f_dentry, 0, 0) != 0) - goto close_fail; - - retval = binfmt->core_dump(signr, regs, file); ---- linux-2.4.18-18.8.0-l12/include/linux/dcache.h~vfs_intent-2.4.18-18 Wed Feb 26 16:54:17 2003 -+++ linux-2.4.18-18.8.0-l12-phil/include/linux/dcache.h Wed Feb 26 17:01:30 2003 -@@ -6,6 +6,25 @@ - #include - #include - -+#define IT_OPEN (1) -+#define IT_CREAT (1<<1) -+#define IT_READDIR (1<<2) -+#define IT_GETATTR (1<<3) -+#define IT_LOOKUP (1<<4) -+#define IT_UNLINK (1<<5) -+ -+struct lookup_intent { -+ int it_op; -+ int it_mode; -+ int it_flags; -+ int it_disposition; -+ int it_status; -+ struct iattr *it_iattr; -+ __u64 it_lock_handle[2]; -+ int it_lock_mode; -+ void *it_data; -+}; -+ - /* - * linux/include/linux/dcache.h - * -@@ -78,6 +97,7 @@ struct dentry { - unsigned long d_time; /* used by d_revalidate */ - struct dentry_operations *d_op; - struct super_block * d_sb; /* The root of the dentry tree */ -+ struct lookup_intent *d_it; - unsigned long d_vfs_flags; - void * d_fsdata; /* fs-specific data */ - void * d_extra_attributes; /* TUX-specific data */ -@@ -91,8 +111,15 @@ struct dentry_operations { - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); -+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); - }; - -+/* defined in fs/namei.c */ -+extern void intent_release(struct dentry *de, struct lookup_intent *it); -+/* defined in fs/dcache.c */ -+extern void __d_rehash(struct dentry * entry, int lock); -+ - /* the dentry parameter passed to d_hash and d_compare is the parent - * directory of the entries to be compared. It is used in case these - * functions need any directory specific information for determining -@@ -124,6 +151,7 @@ d_iput: no no yes - * s_nfsd_free_path semaphore will be down - */ - #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */ -+#define DCACHE_LUSTRE_INVALID 0x0010 /* Lustre invalidated */ - - extern spinlock_t dcache_lock; - ---- linux-2.4.18-18.8.0-l12/include/linux/fs.h~vfs_intent-2.4.18-18 Wed Feb 26 16:54:17 2003 -+++ linux-2.4.18-18.8.0-l12-phil/include/linux/fs.h Wed Feb 26 17:31:42 2003 -@@ -338,6 +338,8 @@ extern void set_bh_page(struct buffer_he - #define ATTR_MTIME_SET 256 - #define ATTR_FORCE 512 /* Not a change, but a change it */ - #define ATTR_ATTR_FLAG 1024 -+#define ATTR_RAW 2048 /* file system, not vfs will massage attrs */ -+#define ATTR_FROM_OPEN 4096 /* called from open path, ie O_TRUNC */ - - /* - * This is the Inode Attributes structure, used for notify_change(). It -@@ -576,6 +578,7 @@ struct file { - - /* needed for tty driver, and maybe others */ - void *private_data; -+ struct lookup_intent *f_intent; - - /* preallocated helper kiobuf to speedup O_DIRECT */ - struct kiobuf *f_iobuf; -@@ -836,7 +839,9 @@ extern int vfs_symlink(struct inode *, s - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it); - - /* - * File types -@@ -897,20 +902,33 @@ struct file_operations { - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *); - int (*link) (struct dentry *,struct inode *,struct dentry *); -+ int (*link2) (struct inode *,struct inode *, const char *, int); - int (*unlink) (struct inode *,struct dentry *); -+ int (*unlink2) (struct inode *, const char *, int); - int (*symlink) (struct inode *,struct dentry *,const char *); -+ int (*symlink2) (struct inode *, const char *, int, const char *); - int (*mkdir) (struct inode *,struct dentry *,int); -+ int (*mkdir2) (struct inode *, const char *, int,int); - int (*rmdir) (struct inode *,struct dentry *); -+ int (*rmdir2) (struct inode *, const char *, int); - int (*mknod) (struct inode *,struct dentry *,int,int); -+ int (*mknod2) (struct inode *, const char *, int,int,int); - int (*rename) (struct inode *, struct dentry *, - struct inode *, struct dentry *); -+ int (*rename2) (struct inode *, struct inode *, -+ const char *oldname, int oldlen, -+ const char *newname, int newlen); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); -+ int (*follow_link2) (struct dentry *, struct nameidata *, -+ struct lookup_intent *it); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*revalidate) (struct dentry *); - int (*setattr) (struct dentry *, struct iattr *); -+ int (*setattr_raw) (struct inode *, struct iattr *); - int (*getattr) (struct dentry *, struct iattr *); - }; - -@@ -1112,7 +1130,7 @@ static inline int get_lease(struct inode - - asmlinkage long sys_open(const char *, int, int); - asmlinkage long sys_close(unsigned int); /* yes, it's really unsigned */ --extern int do_truncate(struct dentry *, loff_t start); -+extern int do_truncate(struct dentry *, loff_t start, int called_from_open); - - extern struct file *filp_open(const char *, int, int); - extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); -@@ -1381,6 +1399,7 @@ typedef int (*read_actor_t)(read_descrip - extern loff_t default_llseek(struct file *file, loff_t offset, int origin); - - extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *)); -+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it)); - extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *)); - extern int FASTCALL(path_walk(const char *, struct nameidata *)); - extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *)); -@@ -1392,6 +1411,8 @@ extern struct dentry * lookup_one_len(co - extern struct dentry * lookup_hash(struct qstr *, struct dentry *); - #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) - #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) -+#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it) -+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it) - - extern void inode_init_once(struct inode *); - extern void iput(struct inode *); -@@ -1492,6 +1513,8 @@ extern struct file_operations generic_ro - - extern int vfs_readlink(struct dentry *, char *, int, const char *); - extern int vfs_follow_link(struct nameidata *, const char *); -+extern int vfs_follow_link_it(struct nameidata *, const char *, -+ struct lookup_intent *it); - extern int page_readlink(struct dentry *, char *, int); - extern int page_follow_link(struct dentry *, struct nameidata *); - extern struct inode_operations page_symlink_inode_operations; ---- linux-2.4.18-18.8.0-l12/kernel/ksyms.c~vfs_intent-2.4.18-18 Wed Feb 26 16:54:17 2003 -+++ linux-2.4.18-18.8.0-l12-phil/kernel/ksyms.c Wed Feb 26 16:54:17 2003 -@@ -293,6 +293,7 @@ EXPORT_SYMBOL(read_cache_page); - EXPORT_SYMBOL(set_page_dirty); - EXPORT_SYMBOL(vfs_readlink); - EXPORT_SYMBOL(vfs_follow_link); -+EXPORT_SYMBOL(vfs_follow_link_it); - EXPORT_SYMBOL(page_readlink); - EXPORT_SYMBOL(page_follow_link); - EXPORT_SYMBOL(page_symlink_inode_operations); diff --git a/lustre/kernel_patches/patches/vfs_intent.patch b/lustre/kernel_patches/patches/vfs_intent.patch deleted file mode 100644 index 75e404b..0000000 --- a/lustre/kernel_patches/patches/vfs_intent.patch +++ /dev/null @@ -1,1158 +0,0 @@ - fs/dcache.c | 8 + - fs/namei.c | 287 ++++++++++++++++++++++++++++++++++++++++--------- - fs/nfsd/vfs.c | 2 - fs/open.c | 53 +++++++-- - fs/stat.c | 9 + - include/linux/dcache.h | 25 ++++ - include/linux/fs.h | 22 +++ - kernel/ksyms.c | 1 - 8 files changed, 344 insertions(+), 63 deletions(-) - ---- linux-2.4.18-18.8.0-l7/fs/dcache.c~vfs_intent-2.4.18-18 Mon Jan 20 08:28:00 2003 -+++ linux-2.4.18-18.8.0-l7-root/fs/dcache.c Mon Jan 20 08:54:54 2003 -@@ -186,6 +188,13 @@ int d_invalidate(struct dentry * dentry) - spin_unlock(&dcache_lock); - return 0; - } -+ -+ /* network invalidation by Lustre */ -+ if (dentry->d_flags & DCACHE_LUSTRE_INVALID) { -+ spin_unlock(&dcache_lock); -+ return 0; -+ } -+ - /* - * Check whether to do a partial shrink_dcache - * to get rid of unused child entries. -@@ -645,6 +654,7 @@ struct dentry * d_alloc(struct dentry * - dentry->d_fsdata = NULL; - dentry->d_extra_attributes = NULL; - dentry->d_mounted = 0; -+ dentry->d_it = NULL; - INIT_LIST_HEAD(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); ---- linux-2.4.18-18.8.0-l7/fs/namei.c~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003 -+++ linux-2.4.18-18.8.0-l7-root/fs/namei.c Wed Jan 22 22:53:28 2003 -@@ -94,6 +97,13 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct dentry *de, struct lookup_intent *it) -+{ -+ if (it && de->d_op && de->d_op->d_intent_release) -+ de->d_op->d_intent_release(de, it); -+ -+} -+ - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the - * kernel data space before using them.. -@@ -260,10 +271,19 @@ void path_release(struct nameidata *nd) - * Internal lookup() using the new generic dcache. - * SMP-safe - */ --static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * dentry = d_lookup(parent, name); - -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { -+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -281,7 +301,8 @@ static struct dentry * cached_lookup(str - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; -@@ -300,6 +321,9 @@ static struct dentry * real_lookup(struc - result = ERR_PTR(-ENOMEM); - if (dentry) { - lock_kernel(); -+ if (dir->i_op->lookup2) -+ result = dir->i_op->lookup2(dir, dentry, it); -+ else - result = dir->i_op->lookup(dir, dentry); - unlock_kernel(); - if (result) -@@ -321,6 +345,12 @@ static struct dentry * real_lookup(struc - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate2) { -+ if (!result->d_op->d_revalidate2(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ result = ERR_PTR(-ENOENT); -+ } - } - return result; - } -@@ -334,7 +364,8 @@ int max_recursive_link = 5; - * Without that kind of total limit, nasty chains of consecutive - * symlinks can cause almost arbitrarily long lookups. - */ --static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) -+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, -+ struct lookup_intent *it) - { - int err; - if (current->link_count >= max_recursive_link) -@@ -348,10 +379,14 @@ static inline int do_follow_link(struct - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -- err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -+ intent_release(dentry, it); - path_release(nd); - return -ELOOP; - } -@@ -449,7 +484,8 @@ static inline void follow_dotdot(struct - * - * We expect 'base' to be positive and a directory. - */ --int link_path_walk(const char * name, struct nameidata *nd) -+int link_path_walk_it(const char *name, struct nameidata *nd, -+ struct lookup_intent *it) - { - struct dentry *dentry; - struct inode *inode; -@@ -526,12 +562,12 @@ int link_path_walk(const char * name, st - break; - } - /* This does the actual lookups.. */ -- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - if (!dentry) { - err = -EWOULDBLOCKIO; - if (atomic) - break; -- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; -@@ -548,8 +584,8 @@ int link_path_walk(const char * name, st - if (!inode->i_op) - goto out_dput; - -- if (inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ if (inode->i_op->follow_link || inode->i_op->follow_link2) { -+ err = do_follow_link(dentry, nd, NULL); - dput(dentry); - if (err) - goto return_err; -@@ -565,7 +601,7 @@ int link_path_walk(const char * name, st - nd->dentry = dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup2) - break; - continue; - /* here ends the main loop */ -@@ -592,12 +628,12 @@ last_component: - if (err < 0) - break; - } -- dentry = cached_lookup(nd->dentry, &this, 0); -+ dentry = cached_lookup(nd->dentry, &this, 0, it); - if (!dentry) { - err = -EWOULDBLOCKIO; - if (atomic) - break; -- dentry = real_lookup(nd->dentry, &this, 0); -+ dentry = real_lookup(nd->dentry, &this, 0, it); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; -@@ -606,8 +642,9 @@ last_component: - ; - inode = dentry->d_inode; - if ((lookup_flags & LOOKUP_FOLLOW) -- && inode && inode->i_op && inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ && inode && inode->i_op && -+ (inode->i_op->follow_link || inode->i_op->follow_link2)) { -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -621,7 +659,8 @@ last_component: - goto no_inode; - if (lookup_flags & LOOKUP_DIRECTORY) { - err = -ENOTDIR; -- if (!inode->i_op || !inode->i_op->lookup) -+ if (!inode->i_op || (!inode->i_op->lookup && -+ !inode->i_op->lookup2)) - break; - } - goto return_base; -@@ -658,15 +697,28 @@ out_dput: - dput(dentry); - break; - } -+ if (err) -+ intent_release(nd->dentry, it); - path_release(nd); - return_err: - return err; - } - -+int link_path_walk(const char * name, struct nameidata *nd) -+{ -+ return link_path_walk_it(name, nd, NULL); -+} -+ -+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it) -+{ -+ current->total_link_count = 0; -+ return link_path_walk_it(name, nd, it); -+} -+ - int path_walk(const char * name, struct nameidata *nd) - { - current->total_link_count = 0; -- return link_path_walk(name, nd); -+ return link_path_walk_it(name, nd, NULL); - } - - /* SMP-safe */ -@@ -751,6 +803,17 @@ walk_init_root(const char *name, struct - } - - /* SMP-safe */ -+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it) -+{ -+ int error = 0; -+ if (path_init(path, flags, nd)) -+ error = path_walk_it(path, nd, it); -+ return error; -+} -+ -+ -+/* SMP-safe */ - int path_lookup(const char *path, unsigned flags, struct nameidata *nd) - { - int error = 0; -@@ -779,7 +842,8 @@ int path_init(const char *name, unsigned - * needs parent already locked. Doesn't follow mounts. - * SMP-safe. - */ --struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, -+ struct lookup_intent *it) - { - struct dentry * dentry; - struct inode *inode; -@@ -802,13 +866,16 @@ struct dentry * lookup_hash(struct qstr - goto out; - } - -- dentry = cached_lookup(base, name, 0); -+ dentry = cached_lookup(base, name, 0, it); - if (!dentry) { - struct dentry *new = d_alloc(base, name); - dentry = ERR_PTR(-ENOMEM); - if (!new) - goto out; - lock_kernel(); -+ if (inode->i_op->lookup2) -+ dentry = inode->i_op->lookup2(inode, new, it); -+ else - dentry = inode->i_op->lookup(inode, new); - unlock_kernel(); - if (!dentry) -@@ -820,6 +887,12 @@ out: - return dentry; - } - -+struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+{ -+ return lookup_hash_it(name, base, NULL); -+} -+ -+ - /* SMP-safe */ - struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) - { -@@ -841,7 +914,7 @@ struct dentry * lookup_one_len(const cha - } - this.hash = end_name_hash(hash); - -- return lookup_hash(&this, base); -+ return lookup_hash_it(&this, base, NULL); - access: - return ERR_PTR(-EACCES); - } -@@ -872,6 +945,23 @@ int __user_walk(const char *name, unsign - return err; - } - -+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it) -+{ -+ char *tmp; -+ int err; -+ -+ tmp = getname(name); -+ err = PTR_ERR(tmp); -+ if (!IS_ERR(tmp)) { -+ err = 0; -+ if (path_init(tmp, flags, nd)) -+ err = path_walk_it(tmp, nd, it); -+ putname(tmp); -+ } -+ return err; -+} -+ - /* - * It's inline, so penalty for filesystems that don't use sticky bit is - * minimal. -@@ -1045,14 +1135,17 @@ int may_open(struct nameidata *nd, int a - return get_lease(inode, flag); - } - -+extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it); -+ - struct file *filp_open(const char * pathname, int open_flags, int mode) - { - int acc_mode, error = 0; -- struct inode *inode; - struct dentry *dentry; - struct dentry *dir; - int flag = open_flags; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = open_flags }; - int count = 0; - - if ((flag+1) & O_ACCMODE) -@@ -1066,7 +1159,7 @@ struct file *filp_open(const char * path - * 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 ERR_PTR(error); - dentry = nd.dentry; -@@ -1076,6 +1169,8 @@ struct file *filp_open(const char * path - /* - * Create - we need to know the parent. - */ -+ it.it_mode = mode; -+ it.it_op |= IT_CREAT; - error = path_lookup(pathname, LOOKUP_PARENT, &nd); - if (error) - return ERR_PTR(error); -@@ -1091,7 +1186,7 @@ struct file *filp_open(const char * path - - 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); -@@ -1100,6 +1195,7 @@ do_last: - goto exit; - } - -+ it.it_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { - error = vfs_create(dir->d_inode, dentry, -@@ -1134,7 +1230,8 @@ do_last: - error = -ENOENT; - if (!dentry->d_inode) - goto exit_dput; -- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) -+ if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || -+ dentry->d_inode->i_op->follow_link2)) - goto do_link; - - dput(nd.dentry); -@@ -1149,11 +1246,13 @@ ok: - if (!S_ISREG(nd.dentry->d_inode->i_mode)) - open_flags &= ~O_TRUNC; - -- return dentry_open(nd.dentry, nd.mnt, open_flags); -+ return dentry_open_it(nd.dentry, nd.mnt, open_flags, &it); - - exit_dput: -+ intent_release(dentry, &it); - dput(dentry); - exit: -+ intent_release(nd.dentry, &it); - path_release(&nd); - return ERR_PTR(error); - -@@ -1172,7 +1271,12 @@ do_link: - * are done. Procfs-like symlinks just set LAST_BIND. - */ - UPDATE_ATIME(dentry->d_inode); -- error = dentry->d_inode->i_op->follow_link(dentry, &nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ error = dentry->d_inode->i_op->follow_link2(dentry, &nd, &it); -+ else -+ error = dentry->d_inode->i_op->follow_link(dentry, &nd); -+ if (error) -+ intent_release(dentry, &it); - dput(dentry); - if (error) - return error; -@@ -1194,13 +1298,15 @@ do_link: - } - dir = nd.dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); - putname(nd.last.name); - goto do_last; - } - -+ - /* 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; - -@@ -1208,7 +1314,7 @@ static struct dentry *lookup_create(stru - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - if (IS_ERR(dentry)) - goto fail; - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) -@@ -1264,7 +1370,19 @@ asmlinkage long sys_mknod(const char * f - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ -+ if (nd.dentry->d_inode->i_op->mknod2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mknod2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ mode, dev); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ -+ dentry = lookup_create(&nd, 0, NULL); - error = PTR_ERR(dentry); - - mode &= ~current->fs->umask; -@@ -1285,6 +1403,7 @@ asmlinkage long sys_mknod(const char * f - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+ out2: - path_release(&nd); - out: - putname(tmp); -@@ -1332,7 +1451,17 @@ asmlinkage long sys_mkdir(const char * p - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 1); -+ if (nd.dentry->d_inode->i_op->mkdir2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mkdir2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ mode); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ dentry = lookup_create(&nd, 1, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_mkdir(nd.dentry->d_inode, dentry, -@@ -1340,6 +1469,7 @@ asmlinkage long sys_mkdir(const char * p - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1440,8 +1570,17 @@ asmlinkage long sys_rmdir(const char * p - error = -EBUSY; - goto exit1; - } -+ if (nd.dentry->d_inode->i_op->rmdir2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->rmdir2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit1; -+ } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); -@@ -1499,8 +1638,17 @@ asmlinkage long sys_unlink(const char * - error = -EISDIR; - if (nd.last_type != LAST_NORM) - goto exit1; -+ if (nd.dentry->d_inode->i_op->unlink2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->unlink2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit1; -+ } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - /* Why not before? Because we want correct error value */ -@@ -1567,15 +1715,26 @@ asmlinkage long sys_symlink(const char * - error = path_lookup(to, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ if (nd.dentry->d_inode->i_op->symlink2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->symlink2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ from); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ dentry = lookup_create(&nd, 0, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_symlink(nd.dentry->d_inode, dentry, from); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+ out2: - path_release(&nd); --out: -+ out: - putname(to); - } - putname(from); -@@ -1642,7 +1801,7 @@ asmlinkage long sys_link(const char * ol - struct dentry *new_dentry; - struct nameidata nd, old_nd; - -- error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd); -+ error = __user_walk_it(oldname, LOOKUP_POSITIVE, &old_nd, NULL); - if (error) - goto exit; - error = path_lookup(to, LOOKUP_PARENT, &nd); -@@ -1651,7 +1810,17 @@ asmlinkage long sys_link(const char * ol - error = -EXDEV; - if (old_nd.mnt != nd.mnt) - goto out_release; -- new_dentry = lookup_create(&nd, 0); -+ if (nd.dentry->d_inode->i_op->link2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->link2(old_nd.dentry->d_inode, -+ nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out_release; -+ } -+ new_dentry = lookup_create(&nd, 0, NULL); - error = PTR_ERR(new_dentry); - if (!IS_ERR(new_dentry)) { - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); -@@ -1695,7 +1864,8 @@ exit: - * locking]. - */ - int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - struct inode *target; -@@ -1753,6 +1923,7 @@ int vfs_rename_dir(struct inode *old_dir - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - if (target) { - if (!error) - target->i_flags |= S_DEAD; -@@ -1774,7 +1945,8 @@ out_unlock: - } - - int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - -@@ -1805,6 +1977,7 @@ int vfs_rename_other(struct inode *old_d - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - double_up(&old_dir->i_zombie, &new_dir->i_zombie); - if (error) - return error; -@@ -1816,13 +1989,14 @@ int vfs_rename_other(struct inode *old_d - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - if (S_ISDIR(old_dentry->d_inode->i_mode)) -- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); - else -- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); - if (!error) { - if (old_dir == new_dir) - inode_dir_notify(old_dir, DN_RENAME); -@@ -1862,9 +2036,23 @@ static inline int do_rename(const char * - if (newnd.last_type != LAST_NORM) - goto exit2; - -+ if (old_dir->d_inode->i_op->rename2) { -+ lock_kernel(); -+ error = old_dir->d_inode->i_op->rename2(old_dir->d_inode, -+ new_dir->d_inode, -+ oldnd.last.name, -+ oldnd.last.len, -+ newnd.last.name, -+ newnd.last.len); -+ unlock_kernel(); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit2; -+ } -+ - double_lock(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -1880,14 +2068,14 @@ static inline int do_rename(const char * - if (newnd.last.name[newnd.last.len]) - goto exit4; - } -- new_dentry = lookup_hash(&newnd.last, new_dir); -+ new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; - - lock_kernel(); - error = vfs_rename(old_dir->d_inode, old_dentry, -- new_dir->d_inode, new_dentry); -+ new_dir->d_inode, new_dentry, NULL); - unlock_kernel(); - - dput(new_dentry); -@@ -1940,7 +2127,8 @@ out: - } - - static inline int --__vfs_follow_link(struct nameidata *nd, const char *link) -+__vfs_follow_link(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) - { - int res = 0; - char *name; -@@ -1953,7 +2141,7 @@ __vfs_follow_link(struct nameidata *nd, - /* weird __emul_prefix() stuff did it */ - goto out; - } -- res = link_path_walk(link, nd); -+ res = link_path_walk_it(link, nd, it); - out: - if (current->link_count || res || nd->last_type!=LAST_NORM) - return res; -@@ -1975,7 +2163,13 @@ fail: - - int vfs_follow_link(struct nameidata *nd, const char *link) - { -- return __vfs_follow_link(nd, link); -+ return __vfs_follow_link(nd, link, NULL); -+} -+ -+int vfs_follow_link_it(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) -+{ -+ return __vfs_follow_link(nd, link, it); - } - - /* get the link contents into pagecache */ -@@ -2017,7 +2211,7 @@ int page_follow_link(struct dentry *dent - { - struct page *page = NULL; - char *s = page_getlink(dentry, &page); -- int res = __vfs_follow_link(nd, s); -+ int res = __vfs_follow_link(nd, s, NULL); - if (page) { - kunmap(page); - page_cache_release(page); ---- linux-2.4.18-18.8.0-l7/fs/nfsd/vfs.c~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003 -+++ linux-2.4.18-18.8.0-l7-root/fs/nfsd/vfs.c Mon Jan 20 12:25:10 2003 -@@ -1298,7 +1298,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); - unlock_kernel(); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); ---- linux-2.4.18-18.8.0-l7/fs/open.c~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003 -+++ linux-2.4.18-18.8.0-l7-root/fs/open.c Wed Jan 22 10:39:31 2003 -@@ -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 @@ static inline long do_sys_truncate(const - struct nameidata nd; - struct inode * inode; - int error; -+ struct lookup_intent it = { .it_op = IT_TRUNC }; - - error = -EINVAL; - if (length < 0) /* sorry, but loff_t says... */ - goto out; - -- error = user_path_walk(path, &nd); -+ error = user_path_walk_it(path, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -168,6 +172,7 @@ static inline long do_sys_truncate(const - put_write_access(inode); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -259,8 +264,9 @@ asmlinkage long sys_utime(char * filenam - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -286,6 +292,7 @@ asmlinkage long sys_utime(char * filenam - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -303,8 +310,9 @@ asmlinkage long sys_utimes(char * filena - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - - if (error) - goto out; -@@ -331,6 +339,7 @@ asmlinkage long sys_utimes(char * filena - } - error = notify_change(nd.dentry, &newattrs); - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -347,6 +356,7 @@ asmlinkage long sys_access(const char * - int old_fsuid, old_fsgid; - kernel_cap_t old_cap; - int res; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ - return -EINVAL; -@@ -364,13 +374,14 @@ asmlinkage long sys_access(const char * - else - current->cap_effective = current->cap_permitted; - -- res = user_path_walk(filename, &nd); -+ res = user_path_walk_it(filename, &nd, &it); - if (!res) { - res = permission(nd.dentry->d_inode, mode); - /* SuS v2 requires we report a read only fs too */ - if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) - && !special_file(nd.dentry->d_inode->i_mode)) - res = -EROFS; -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - -@@ -385,8 +396,11 @@ asmlinkage long sys_chdir(const char * f - { - int error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd); -+ error = __user_walk_it(filename, -+ LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, -+ &nd, &it); - if (error) - goto out; - -@@ -397,6 +411,7 @@ asmlinkage long sys_chdir(const char * f - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -436,9 +451,10 @@ asmlinkage long sys_chroot(const char * - { - int error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -- LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); -+ error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -+ LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it); - if (error) - goto out; - -@@ -454,6 +470,7 @@ asmlinkage long sys_chroot(const char * - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -498,8 +515,9 @@ asmlinkage long sys_chmod(const char * f - struct inode * inode; - int error; - struct iattr newattrs; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -519,6 +537,7 @@ asmlinkage long sys_chmod(const char * f - error = notify_change(nd.dentry, &newattrs); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -588,10 +607,12 @@ asmlinkage long sys_chown(const char * f - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = chown_common(nd.dentry, user, group); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -601,10 +622,12 @@ asmlinkage long sys_lchown(const char * - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_SETATTR }; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = chown_common(nd.dentry, user, group); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -628,7 +651,8 @@ extern ssize_t do_readahead(struct file - /* 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; -@@ -693,6 +717,7 @@ struct file *dentry_open(struct dentry * - do_readahead(f, 0, (48 * 1024) >> PAGE_SHIFT); - - -+ intent_release(dentry, it); - return f; - - cleanup_all: -@@ -707,11 +732,17 @@ cleanup_all: - cleanup_file: - put_filp(f); - cleanup_dentry: -+ intent_release(dentry, it); - dput(dentry); - mntput(mnt); - return ERR_PTR(error); - } - -+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+{ -+ return dentry_open_it(dentry, mnt, flags, NULL); -+} -+ - /* - * Find an empty file descriptor entry, and mark it busy. - */ ---- linux-2.4.18-18.8.0-l7/fs/stat.c~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003 -+++ linux-2.4.18-18.8.0-l7-root/fs/stat.c Mon Jan 20 12:25:10 2003 -@@ -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 @@ int vfs_stat(char *name, struct kstat *s - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk(name, &nd); -+ error = user_path_walk_it(name, &nd, &it); - if (!error) { - error = do_getattr(nd.mnt, nd.dentry, stat); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -117,10 +120,12 @@ int vfs_lstat(char *name, struct kstat * - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk_link(name, &nd); -+ error = user_path_walk_link_it(name, &nd, &it); - if (!error) { - error = do_getattr(nd.mnt, nd.dentry, stat); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; ---- linux-2.4.18-18.8.0-l7/include/linux/dcache.h~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003 -+++ linux-2.4.18-18.8.0-l7-root/include/linux/dcache.h Wed Jan 22 19:38:12 2003 -@@ -6,6 +6,27 @@ - #include - #include - -+#define IT_OPEN (1) -+#define IT_CREAT (1<<1) -+#define IT_READDIR (1<<2) -+#define IT_GETATTR (1<<3) -+#define IT_SETATTR (1<<4) -+#define IT_TRUNC (1<<5) -+#define IT_READLINK (1<<6) -+#define IT_LOOKUP (1<<7) -+ -+struct lookup_intent { -+ int it_op; -+ int it_mode; -+ int it_flags; -+ int it_disposition; -+ int it_status; -+ struct iattr *it_iattr; -+ __u64 it_lock_handle[2]; -+ int it_lock_mode; -+ void *it_data; -+}; -+ - /* - * linux/include/linux/dcache.h - * -@@ -78,6 +99,7 @@ struct dentry { - unsigned long d_time; /* used by d_revalidate */ - struct dentry_operations *d_op; - struct super_block * d_sb; /* The root of the dentry tree */ -+ struct lookup_intent *d_it; - unsigned long d_vfs_flags; - void * d_fsdata; /* fs-specific data */ - void * d_extra_attributes; /* TUX-specific data */ -@@ -91,6 +113,8 @@ struct dentry_operations { - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); -+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); - }; - - /* the dentry parameter passed to d_hash and d_compare is the parent -@@ -124,6 +148,7 @@ d_iput: no no yes - * s_nfsd_free_path semaphore will be down - */ - #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */ -+#define DCACHE_LUSTRE_INVALID 0x0010 /* Lustre invalidated */ - - extern spinlock_t dcache_lock; - ---- linux-2.4.18-18.8.0-l7/include/linux/fs.h~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003 -+++ linux-2.4.18-18.8.0-l7-root/include/linux/fs.h Wed Jan 22 22:46:13 2003 -@@ -576,6 +576,7 @@ struct file { - - /* needed for tty driver, and maybe others */ - void *private_data; -+ struct lookup_intent *f_intent; - - /* preallocated helper kiobuf to speedup O_DIRECT */ - struct kiobuf *f_iobuf; -@@ -836,7 +837,9 @@ extern int vfs_symlink(struct inode *, s - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it); - - /* - * File types -@@ -897,16 +900,28 @@ struct file_operations { - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *); - int (*link) (struct dentry *,struct inode *,struct dentry *); -+ int (*link2) (struct inode *,struct inode *, const char *, int); - int (*unlink) (struct inode *,struct dentry *); -+ int (*unlink2) (struct inode *, const char *, int); - int (*symlink) (struct inode *,struct dentry *,const char *); -+ int (*symlink2) (struct inode *, const char *, int, const char *); - int (*mkdir) (struct inode *,struct dentry *,int); -+ int (*mkdir2) (struct inode *, const char *, int,int); - int (*rmdir) (struct inode *,struct dentry *); -+ int (*rmdir2) (struct inode *, const char *, int); - int (*mknod) (struct inode *,struct dentry *,int,int); -+ int (*mknod2) (struct inode *, const char *, int,int,int); - int (*rename) (struct inode *, struct dentry *, - struct inode *, struct dentry *); -+ int (*rename2) (struct inode *, struct inode *, -+ const char *oldname, int oldlen, -+ const char *newname, int newlen); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); -+ int (*follow_link2) (struct dentry *, struct nameidata *, -+ struct lookup_intent *it); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*revalidate) (struct dentry *); -@@ -1381,6 +1396,7 @@ typedef int (*read_actor_t)(read_descrip - extern loff_t default_llseek(struct file *file, loff_t offset, int origin); - - extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *)); -+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it)); - extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *)); - extern int FASTCALL(path_walk(const char *, struct nameidata *)); - extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *)); -@@ -1392,6 +1408,8 @@ extern struct dentry * lookup_one_len(co - extern struct dentry * lookup_hash(struct qstr *, struct dentry *); - #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) - #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) -+#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it) -+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it) - - extern void inode_init_once(struct inode *); - extern void iput(struct inode *); -@@ -1492,6 +1510,8 @@ extern struct file_operations generic_ro - - extern int vfs_readlink(struct dentry *, char *, int, const char *); - extern int vfs_follow_link(struct nameidata *, const char *); -+extern int vfs_follow_link_it(struct nameidata *, const char *, -+ struct lookup_intent *it); - extern int page_readlink(struct dentry *, char *, int); - extern int page_follow_link(struct dentry *, struct nameidata *); - extern struct inode_operations page_symlink_inode_operations; ---- linux-2.4.18-18.8.0-l7/kernel/ksyms.c~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003 -+++ linux-2.4.18-18.8.0-l7-root/kernel/ksyms.c Mon Jan 20 12:25:10 2003 -@@ -293,6 +293,7 @@ EXPORT_SYMBOL(read_cache_page); - EXPORT_SYMBOL(set_page_dirty); - EXPORT_SYMBOL(vfs_readlink); - EXPORT_SYMBOL(vfs_follow_link); -+EXPORT_SYMBOL(vfs_follow_link_it); - EXPORT_SYMBOL(page_readlink); - EXPORT_SYMBOL(page_follow_link); - EXPORT_SYMBOL(page_symlink_inode_operations); - -_ diff --git a/lustre/kernel_patches/patches/vfs_intent_hp.patch b/lustre/kernel_patches/patches/vfs_intent_hp.patch deleted file mode 100644 index fa0998a..0000000 --- a/lustre/kernel_patches/patches/vfs_intent_hp.patch +++ /dev/null @@ -1,1526 +0,0 @@ - fs/dcache.c | 8 - fs/namei.c | 335 +++++++++++++++++---- - fs/nfsd/vfs.c | 2 - fs/open.c | 142 +++++++- - fs/stat.c | 24 + - include/linux/dcache.h | 26 + - include/linux/fs.h | 27 + - kernel/ksyms.c | 1 - fs/exec.c | 18 - - 9 files changed, 487 insertions(+), 96 deletions(-) - ---- linux-2.4.19-hp2_pnnl4/fs/dcache.c~vfs_intent_hp Sun Jan 19 19:04:47 2003 -+++ linux-2.4.19-hp2_pnnl4-root/fs/dcache.c Sun Jan 19 19:04:47 2003 -@@ -186,6 +188,13 @@ int d_invalidate(struct dentry * dentry) - spin_unlock(&dcache_lock); - return 0; - } -+ -+ /* network invalidation by Lustre */ -+ if (dentry->d_flags & DCACHE_LUSTRE_INVALID) { -+ spin_unlock(&dcache_lock); -+ return 0; -+ } -+ - /* - * Check whether to do a partial shrink_dcache - * to get rid of unused child entries. -@@ -616,6 +618,7 @@ struct dentry * d_alloc(struct dentry * - dentry->d_op = NULL; - dentry->d_fsdata = NULL; - dentry->d_mounted = 0; -+ dentry->d_it = NULL; - INIT_LIST_HEAD(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); -@@ -859,13 +867,19 @@ void d_delete(struct dentry * dentry) - * Adds a dentry to the hash according to its name. - */ - --void d_rehash(struct dentry * entry) -+void __d_rehash(struct dentry * entry, int lock) - { - struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash); - if (!list_empty(&entry->d_hash)) BUG(); -- spin_lock(&dcache_lock); -+ if (lock) spin_lock(&dcache_lock); - list_add(&entry->d_hash, list); -- spin_unlock(&dcache_lock); -+ if (lock) spin_unlock(&dcache_lock); -+} -+EXPORT_SYMBOL(__d_rehash); -+ -+void d_rehash(struct dentry * entry) -+{ -+ __d_rehash(entry, 1); - } - - #define do_switch(x,y) do { \ ---- linux-2.4.19-hp2_pnnl4/fs/namei.c~vfs_intent_hp Sun Jan 19 19:04:47 2003 -+++ linux-2.4.19-hp2_pnnl4-root/fs/namei.c Sun Jan 19 19:35:55 2003 -@@ -94,6 +97,13 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct dentry *de, struct lookup_intent *it) -+{ -+ if (it && de->d_op && de->d_op->d_intent_release) -+ de->d_op->d_intent_release(de, it); -+ -+} -+ - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the - * kernel data space before using them.. -@@ -260,10 +271,19 @@ void path_release(struct nameidata *nd) - * Internal lookup() using the new generic dcache. - * SMP-safe - */ --static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * dentry = d_lookup(parent, name); - -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { -+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -281,11 +301,14 @@ static struct dentry * cached_lookup(str - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; - -+again: -+ - down(&dir->i_sem); - /* - * First re-do the cached lookup just in case it was created -@@ -300,6 +321,9 @@ static struct dentry * real_lookup(struc - result = ERR_PTR(-ENOMEM); - if (dentry) { - lock_kernel(); -+ if (dir->i_op->lookup2) -+ result = dir->i_op->lookup2(dir, dentry, it); -+ else - result = dir->i_op->lookup(dir, dentry); - unlock_kernel(); - if (result) -@@ -321,6 +345,12 @@ static struct dentry * real_lookup(struc - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate2) { -+ if (!result->d_op->d_revalidate2(result, flags, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ goto again; -+ } - } - return result; - } -@@ -332,7 +362,8 @@ static struct dentry * real_lookup(struc - * Without that kind of total limit, nasty chains of consecutive - * symlinks can cause almost arbitrarily long lookups. - */ --static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) -+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, -+ struct lookup_intent *it) - { - int err; - if (current->link_count >= 5) -@@ -346,10 +377,14 @@ static inline int do_follow_link(struct - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -- err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -+ intent_release(dentry, it); - path_release(nd); - return -ELOOP; - } -@@ -381,15 +416,26 @@ int follow_up(struct vfsmount **mnt, str - return __follow_up(mnt, dentry); - } - --static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry) -+static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry, -+ struct lookup_intent *it) - { - struct vfsmount *mounted; - - spin_lock(&dcache_lock); - mounted = lookup_mnt(*mnt, *dentry); - if (mounted) { -+ int opc = 0, mode = 0; - *mnt = mntget(mounted); - spin_unlock(&dcache_lock); -+ if (it) { -+ opc = it->it_op; -+ mode = it->it_mode; -+ } -+ intent_release(*dentry, it); -+ if (it) { -+ it->it_op = opc; -+ it->it_mode = mode; -+ } - dput(*dentry); - mntput(mounted->mnt_parent); - *dentry = dget(mounted->mnt_root); -@@ -401,7 +447,7 @@ static inline int __follow_down(struct v - - int follow_down(struct vfsmount **mnt, struct dentry **dentry) - { -- return __follow_down(mnt,dentry); -+ return __follow_down(mnt,dentry,NULL); - } - - static inline void follow_dotdot(struct nameidata *nd) -@@ -437,7 +483,7 @@ static inline void follow_dotdot(struct - mntput(nd->mnt); - nd->mnt = parent; - } -- while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry)) -+ while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry, NULL)) - ; - } - -@@ -447,7 +482,8 @@ static inline void follow_dotdot(struct - * - * We expect 'base' to be positive and a directory. - */ --int link_path_walk(const char * name, struct nameidata *nd) -+int link_path_walk_it(const char *name, struct nameidata *nd, -+ struct lookup_intent *it) - { - struct dentry *dentry; - struct inode *inode; -@@ -520,15 +556,15 @@ int link_path_walk(const char * name, st - break; - } - /* This does the actual lookups.. */ -- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - if (!dentry) { -- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; - } - /* Check mountpoints.. */ -- while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry)) -+ while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL)) - ; - - err = -ENOENT; -@@ -539,8 +575,8 @@ int link_path_walk(const char * name, st - if (!inode->i_op) - goto out_dput; - -- if (inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ if (inode->i_op->follow_link || inode->i_op->follow_link2) { -+ err = do_follow_link(dentry, nd, NULL); - dput(dentry); - if (err) - goto return_err; -@@ -556,7 +592,7 @@ int link_path_walk(const char * name, st - nd->dentry = dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup2) - break; - continue; - /* here ends the main loop */ -@@ -583,19 +619,20 @@ last_component: - if (err < 0) - break; - } -- dentry = cached_lookup(nd->dentry, &this, 0); -+ dentry = cached_lookup(nd->dentry, &this, 0, it); - if (!dentry) { -- dentry = real_lookup(nd->dentry, &this, 0); -+ dentry = real_lookup(nd->dentry, &this, 0, it); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; - } -- while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry)) -+ while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, it)) - ; - inode = dentry->d_inode; - if ((lookup_flags & LOOKUP_FOLLOW) -- && inode && inode->i_op && inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ && inode && inode->i_op && -+ (inode->i_op->follow_link || inode->i_op->follow_link2)) { -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -609,7 +647,8 @@ last_component: - goto no_inode; - if (lookup_flags & LOOKUP_DIRECTORY) { - err = -ENOTDIR; -- if (!inode->i_op || !inode->i_op->lookup) -+ if (!inode->i_op || -+ (!inode->i_op->lookup && !inode->i_op->lookup2)) - break; - } - goto return_base; -@@ -646,15 +685,28 @@ out_dput: - dput(dentry); - break; - } -+ if (err) -+ intent_release(nd->dentry, it); - path_release(nd); - return_err: - return err; - } - -+int link_path_walk(const char * name, struct nameidata *nd) -+{ -+ return link_path_walk_it(name, nd, NULL); -+} -+ -+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it) -+{ -+ current->total_link_count = 0; -+ return link_path_walk_it(name, nd, it); -+} -+ - int path_walk(const char * name, struct nameidata *nd) - { - current->total_link_count = 0; -- return link_path_walk(name, nd); -+ return link_path_walk_it(name, nd, NULL); - } - - /* SMP-safe */ -@@ -757,7 +809,8 @@ int path_init(const char *name, unsigned - * needs parent already locked. Doesn't follow mounts. - * SMP-safe. - */ --struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, -+ struct lookup_intent *it) - { - struct dentry * dentry; - struct inode *inode; -@@ -780,13 +833,16 @@ struct dentry * lookup_hash(struct qstr - goto out; - } - -- dentry = cached_lookup(base, name, 0); -+ dentry = cached_lookup(base, name, 0, it); - if (!dentry) { - struct dentry *new = d_alloc(base, name); - dentry = ERR_PTR(-ENOMEM); - if (!new) - goto out; - lock_kernel(); -+ if (inode->i_op->lookup2) -+ dentry = inode->i_op->lookup2(inode, new, it); -+ else - dentry = inode->i_op->lookup(inode, new); - unlock_kernel(); - if (!dentry) -@@ -798,6 +854,12 @@ out: - return dentry; - } - -+struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+{ -+ return lookup_hash_it(name, base, NULL); -+} -+ -+ - /* SMP-safe */ - struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) - { -@@ -819,7 +881,7 @@ struct dentry * lookup_one_len(const cha - } - this.hash = end_name_hash(hash); - -- return lookup_hash(&this, base); -+ return lookup_hash_it(&this, base, NULL); - access: - return ERR_PTR(-EACCES); - } -@@ -851,6 +913,23 @@ int __user_walk(const char *name, unsign - return err; - } - -+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it) -+{ -+ char *tmp; -+ int err; -+ -+ tmp = getname(name); -+ err = PTR_ERR(tmp); -+ if (!IS_ERR(tmp)) { -+ err = 0; -+ if (path_init(tmp, flags, nd)) -+ err = path_walk_it(tmp, nd, it); -+ putname(tmp); -+ } -+ return err; -+} -+ - /* - * It's inline, so penalty for filesystems that don't use sticky bit is - * minimal. -@@ -987,7 +1066,8 @@ exit_lock: - * for symlinks (where the permissions are checked later). - * SMP-safe - */ --int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) -+int open_namei_it(const char *pathname, int flag, int mode, -+ struct nameidata *nd, struct lookup_intent *it) - { - int acc_mode, error = 0; - struct inode *inode; -@@ -1002,7 +1082,7 @@ int open_namei(const char * pathname, in - */ - if (!(flag & O_CREAT)) { - if (path_init(pathname, lookup_flags(flag), nd)) -- error = path_walk(pathname, nd); -+ error = path_walk_it(pathname, nd, it); - if (error) - return error; - dentry = nd->dentry; -@@ -1012,6 +1092,10 @@ int open_namei(const char * pathname, in - /* - * Create - we need to know the parent. - */ -+ if (it) { -+ it->it_mode = mode; -+ it->it_op |= IT_CREAT; -+ } - if (path_init(pathname, LOOKUP_PARENT, nd)) - error = path_walk(pathname, nd); - if (error) -@@ -1028,7 +1112,7 @@ int open_namei(const char * pathname, in - - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - - do_last: - error = PTR_ERR(dentry); -@@ -1037,6 +1121,7 @@ do_last: - goto exit; - } - -+ it->it_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { - if (!IS_POSIXACL(dir->d_inode)) -@@ -1066,12 +1151,13 @@ do_last: - error = -ELOOP; - if (flag & O_NOFOLLOW) - goto exit_dput; -- while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry)); -+ while (__follow_down(&nd->mnt,&dentry,it) && d_mountpoint(dentry)); - } - error = -ENOENT; - if (!dentry->d_inode) - goto exit_dput; -- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) -+ if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || -+ dentry->d_inode->i_op->follow_link2)) - goto do_link; - - dput(nd->dentry); -@@ -1145,7 +1231,7 @@ do_last: - if (!error) { - DQUOT_INIT(inode); - -- error = do_truncate(dentry, 0); -+ error = do_truncate(dentry, 0, 1); - } - put_write_access(inode); - if (error) -@@ -1157,8 +1243,10 @@ ok: - return 0; - - exit_dput: -+ intent_release(dentry, it); - dput(dentry); - exit: -+ intent_release(nd->dentry, it); - path_release(nd); - return error; - -@@ -1177,7 +1265,12 @@ do_link: - * are done. Procfs-like symlinks just set LAST_BIND. - */ - UPDATE_ATIME(dentry->d_inode); -- error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ error = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (error) -+ intent_release(dentry, it); - dput(dentry); - if (error) - return error; -@@ -1199,13 +1292,20 @@ do_link: - } - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - putname(nd->last.name); - goto do_last; - } - -+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd) -+{ -+ return open_namei_it(pathname, flag, mode, nd, NULL); -+} -+ -+ - /* SMP-safe */ --static struct dentry *lookup_create(struct nameidata *nd, int is_dir) -+static struct dentry *lookup_create(struct nameidata *nd, int is_dir, -+ struct lookup_intent *it) - { - struct dentry *dentry; - -@@ -1213,7 +1313,7 @@ static struct dentry *lookup_create(stru - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); - if (IS_ERR(dentry)) - goto fail; - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) -@@ -1270,7 +1371,19 @@ asmlinkage long sys_mknod(const char * f - error = path_walk(tmp, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ -+ if (nd.dentry->d_inode->i_op->mknod2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mknod2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ mode, dev); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ -+ dentry = lookup_create(&nd, 0, NULL); - error = PTR_ERR(dentry); - - if (!IS_POSIXACL(nd.dentry->d_inode)) -@@ -1289,6 +1402,7 @@ asmlinkage long sys_mknod(const char * f - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1340,15 +1456,25 @@ asmlinkage long sys_mkdir(const char * p - error = path_walk(tmp, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 1); -+ if (nd.dentry->d_inode->i_op->mkdir2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mkdir2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ mode); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ dentry = lookup_create(&nd, 1, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { -- if (!IS_POSIXACL(nd.dentry->d_inode)) -- mode &= ~current->fs->umask; -- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); -+ error = vfs_mkdir(nd.dentry->d_inode, dentry, -+ mode & ~current->fs->umask); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1450,8 +1578,33 @@ asmlinkage long sys_rmdir(const char * p - error = -EBUSY; - goto exit1; - } -+ if (nd.dentry->d_inode->i_op->rmdir2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ struct dentry *last; -+ -+ down(&nd.dentry->d_inode->i_sem); -+ last = lookup_hash_it(&nd.last, nd.dentry, NULL); -+ up(&nd.dentry->d_inode->i_sem); -+ if (IS_ERR(last)) { -+ error = PTR_ERR(last); -+ goto exit1; -+ } -+ if (d_mountpoint(last)) { -+ dput(last); -+ error = -EBUSY; -+ goto exit1; -+ } -+ dput(last); -+ -+ error = op->rmdir2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit1; -+ } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); -@@ -1510,8 +1649,17 @@ asmlinkage long sys_unlink(const char * - error = -EISDIR; - if (nd.last_type != LAST_NORM) - goto exit1; -+ if (nd.dentry->d_inode->i_op->unlink2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->unlink2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit1; -+ } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - /* Why not before? Because we want correct error value */ -@@ -1579,15 +1729,26 @@ asmlinkage long sys_symlink(const char * - error = path_walk(to, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ if (nd.dentry->d_inode->i_op->symlink2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->symlink2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ from); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ dentry = lookup_create(&nd, 0, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_symlink(nd.dentry->d_inode, dentry, from); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+ out2: - path_release(&nd); --out: -+ out: - putname(to); - } - putname(from); -@@ -1660,7 +1824,7 @@ asmlinkage long sys_link(const char * ol - - error = 0; - if (path_init(from, LOOKUP_POSITIVE, &old_nd)) -- error = path_walk(from, &old_nd); -+ error = path_walk_it(from, &old_nd, NULL); - if (error) - goto exit; - if (path_init(to, LOOKUP_PARENT, &nd)) -@@ -1670,7 +1834,17 @@ asmlinkage long sys_link(const char * ol - error = -EXDEV; - if (old_nd.mnt != nd.mnt) - goto out_release; -- new_dentry = lookup_create(&nd, 0); -+ if (nd.dentry->d_inode->i_op->link2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->link2(old_nd.dentry->d_inode, -+ nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out_release; -+ } -+ new_dentry = lookup_create(&nd, 0, NULL); - error = PTR_ERR(new_dentry); - if (!IS_ERR(new_dentry)) { - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); -@@ -1716,7 +1892,8 @@ exit: - * locking]. - */ - int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - struct inode *target; -@@ -1753,6 +1923,7 @@ int vfs_rename_dir(struct inode *old_dir - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - if (target) { - if (!error) - target->i_flags |= S_DEAD; -@@ -1795,7 +1973,8 @@ out_unlock: - } - - int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - -@@ -1826,6 +2005,7 @@ int vfs_rename_other(struct inode *old_d - error = -EBUSY; - else - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); -+ intent_release(new_dentry, it); - double_up(&old_dir->i_zombie, &new_dir->i_zombie); - if (error) - return error; -@@ -1837,13 +2017,14 @@ int vfs_rename_other(struct inode *old_d - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it) - { - int error; - if (S_ISDIR(old_dentry->d_inode->i_mode)) -- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); - else -- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); - if (!error) { - if (old_dir == new_dir) - inode_dir_notify(old_dir, DN_RENAME); -@@ -1888,7 +2070,7 @@ static inline int do_rename(const char * - - double_lock(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -1904,16 +2086,37 @@ static inline int do_rename(const char * - if (newnd.last.name[newnd.last.len]) - goto exit4; - } -- new_dentry = lookup_hash(&newnd.last, new_dir); -+ new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; - -+ if (old_dir->d_inode->i_op->rename2) { -+ lock_kernel(); -+ /* don't rename mount point. mds will take care of -+ * the rest sanity checking */ -+ if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) { -+ error = -EBUSY; -+ goto exit5; -+ } -+ -+ error = old_dir->d_inode->i_op->rename2(old_dir->d_inode, -+ new_dir->d_inode, -+ oldnd.last.name, -+ oldnd.last.len, -+ newnd.last.name, -+ newnd.last.len); -+ unlock_kernel(); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit5; -+ } -+ - lock_kernel(); - error = vfs_rename(old_dir->d_inode, old_dentry, -- new_dir->d_inode, new_dentry); -+ new_dir->d_inode, new_dentry, NULL); - unlock_kernel(); -- -+exit5: - dput(new_dentry); - exit4: - dput(old_dentry); -@@ -1964,7 +2163,8 @@ out: - } - - static inline int --__vfs_follow_link(struct nameidata *nd, const char *link) -+__vfs_follow_link(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) - { - int res = 0; - char *name; -@@ -1977,7 +2177,7 @@ __vfs_follow_link(struct nameidata *nd, - /* weird __emul_prefix() stuff did it */ - goto out; - } -- res = link_path_walk(link, nd); -+ res = link_path_walk_it(link, nd, it); - out: - if (current->link_count || res || nd->last_type!=LAST_NORM) - return res; -@@ -1999,7 +2199,13 @@ fail: - - int vfs_follow_link(struct nameidata *nd, const char *link) - { -- return __vfs_follow_link(nd, link); -+ return __vfs_follow_link(nd, link, NULL); -+} -+ -+int vfs_follow_link_it(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) -+{ -+ return __vfs_follow_link(nd, link, it); - } - - /* get the link contents into pagecache */ -@@ -2041,7 +2247,7 @@ int page_follow_link(struct dentry *dent - { - struct page *page = NULL; - char *s = page_getlink(dentry, &page); -- int res = __vfs_follow_link(nd, s); -+ int res = __vfs_follow_link(nd, s, NULL); - if (page) { - kunmap(page); - page_cache_release(page); ---- linux-2.4.19-hp2_pnnl4/fs/nfsd/vfs.c~vfs_intent_hp Sun Jan 19 19:04:47 2003 -+++ linux-2.4.19-hp2_pnnl4-root/fs/nfsd/vfs.c Sun Jan 19 19:37:57 2003 -@@ -1295,7 +1295,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); - nfsd_sync_dir(fdentry); ---- linux-2.4.19-hp2_pnnl4/fs/open.c~vfs_intent_hp Sun Jan 19 19:04:47 2003 -+++ linux-2.4.19-hp2_pnnl4-root/fs/open.c Sun Jan 19 19:41:00 2003 -@@ -19,6 +19,8 @@ - #include - - #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) -+extern int path_walk_it(const char *name, struct nameidata *nd, -+ struct lookup_intent *it); - - int vfs_statfs(struct super_block *sb, struct statfs *buf) - { -@@ -95,9 +97,10 @@ void fd_install(unsigned int fd, struct - write_unlock(&files->file_lock); - } - --int do_truncate(struct dentry *dentry, loff_t length) -+int do_truncate(struct dentry *dentry, loff_t length, int called_from_open) - { - struct inode *inode = dentry->d_inode; -+ struct inode_operations *op = dentry->d_inode->i_op; - int error; - struct iattr newattrs; - -@@ -108,7 +111,14 @@ int do_truncate(struct dentry *dentry, l - down(&inode->i_sem); - newattrs.ia_size = length; - newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; -- error = notify_change(dentry, &newattrs); -+ if (called_from_open) -+ newattrs.ia_valid |= ATTR_FROM_OPEN; -+ if (op->setattr_raw) { -+ newattrs.ia_valid |= ATTR_RAW; -+ newattrs.ia_ctime = CURRENT_TIME; -+ error = op->setattr_raw(inode, &newattrs); -+ } else -+ error = notify_change(dentry, &newattrs); - up(&inode->i_sem); - return error; - } -@@ -118,12 +121,13 @@ static inline long do_sys_truncate(const - struct nameidata nd; - struct inode * inode; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - error = -EINVAL; - if (length < 0) /* sorry, but loff_t says... */ - goto out; - -- error = user_path_walk(path, &nd); -+ error = user_path_walk_it(path, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -163,11 +167,13 @@ static inline long do_sys_truncate(const - error = locks_verify_truncate(inode, NULL, length); - if (!error) { - DQUOT_INIT(inode); -- error = do_truncate(nd.dentry, length); -+ intent_release(nd.dentry, &it); -+ error = do_truncate(nd.dentry, length, 0); - } - put_write_access(inode); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -215,7 +228,7 @@ static inline long do_sys_ftruncate(unsi - - error = locks_verify_truncate(inode, file, length); - if (!error) -- error = do_truncate(dentry, length); -+ error = do_truncate(dentry, length, 0); - out_putf: - fput(file); - out: -@@ -260,11 +273,13 @@ asmlinkage long sys_utime(char * filenam - struct inode * inode; - struct iattr newattrs; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, NULL); - if (error) - goto out; - inode = nd.dentry->d_inode; - -+ /* this is safe without a Lustre lock because it only depends -+ on the super block */ - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; -@@ -279,11 +294,29 @@ asmlinkage long sys_utime(char * filenam - goto dput_and_out; - - newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; -- } else { -+ } -+ -+ if (inode->i_op->setattr_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ -+ newattrs.ia_valid |= ATTR_RAW; -+ error = op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto dput_and_out; -+ } -+ -+ error = -EROFS; -+ if (IS_RDONLY(inode)) -+ goto dput_and_out; -+ -+ error = -EPERM; -+ if (!times) { - if (current->fsuid != inode->i_uid && - (error = permission(inode,MAY_WRITE)) != 0) - goto dput_and_out; - } -+ - error = notify_change(nd.dentry, &newattrs); - dput_and_out: - path_release(&nd); -@@ -304,12 +337,14 @@ asmlinkage long sys_utimes(char * filena - struct inode * inode; - struct iattr newattrs; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, NULL); - - if (error) - goto out; - inode = nd.dentry->d_inode; - -+ /* this is safe without a Lustre lock because it only depends -+ on the super block */ - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; -@@ -324,7 +359,20 @@ asmlinkage long sys_utimes(char * filena - newattrs.ia_atime = times[0].tv_sec; - newattrs.ia_mtime = times[1].tv_sec; - newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; -- } else { -+ } -+ -+ if (inode->i_op->setattr_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ -+ newattrs.ia_valid |= ATTR_RAW; -+ error = op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto dput_and_out; -+ } -+ -+ error = -EPERM; -+ if (!utimes) { - if (current->fsuid != inode->i_uid && - (error = permission(inode,MAY_WRITE)) != 0) - goto dput_and_out; -@@ -347,6 +356,7 @@ asmlinkage long sys_access(const char * - int old_fsuid, old_fsgid; - kernel_cap_t old_cap; - int res; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ - return -EINVAL; -@@ -364,13 +374,14 @@ asmlinkage long sys_access(const char * - else - current->cap_effective = current->cap_permitted; - -- res = user_path_walk(filename, &nd); -+ res = user_path_walk_it(filename, &nd, &it); - if (!res) { - res = permission(nd.dentry->d_inode, mode); - /* SuS v2 requires we report a read only fs too */ - if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) - && !special_file(nd.dentry->d_inode->i_mode)) - res = -EROFS; -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - -@@ -386,6 +397,7 @@ asmlinkage long sys_chdir(const char * f - int error; - struct nameidata nd; - char *name; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - name = getname(filename); - error = PTR_ERR(name); -@@ -394,7 +406,7 @@ asmlinkage long sys_chdir(const char * f - - 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; -@@ -406,6 +418,7 @@ asmlinkage long sys_chdir(const char * f - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -446,6 +459,7 @@ asmlinkage long sys_chroot(const char * - int error; - struct nameidata nd; - char *name; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - name = getname(filename); - error = PTR_ERR(name); -@@ -454,7 +468,7 @@ asmlinkage long sys_chroot(const char * - - 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; -@@ -471,6 +485,7 @@ asmlinkage long sys_chroot(const char * - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(nd.dentry, &it); - path_release(&nd); - out: - return error; -@@ -508,6 +564,18 @@ asmlinkage long sys_chmod(const char * f - if (IS_RDONLY(inode)) - goto dput_and_out; - -+ if (inode->i_op->setattr_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ -+ newattrs.ia_mode = mode; -+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -+ newattrs.ia_valid |= ATTR_RAW; -+ error = op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto dput_and_out; -+ } -+ - error = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto dput_and_out; -@@ -538,6 +606,20 @@ static int chown_common(struct dentry * - error = -EROFS; - if (IS_RDONLY(inode)) - goto out; -+ -+ if (inode->i_op->setattr_raw) { -+ struct inode_operations *op = dentry->d_inode->i_op; -+ -+ newattrs.ia_uid = user; -+ newattrs.ia_gid = group; -+ newattrs.ia_valid = ATTR_UID | ATTR_GID; -+ newattrs.ia_valid |= ATTR_RAW; -+ error = op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ return error; -+ } -+ - error = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto out; -@@ -655,10 +676,16 @@ asmlinkage long sys_fchown(unsigned int - * for the internal routines (ie open_namei()/follow_link() etc). 00 is - * used by symlinks. - */ -+extern int open_namei_it(const char *filename, int namei_flags, int mode, -+ struct nameidata *nd, struct lookup_intent *it); -+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it); -+ - struct file *filp_open(const char * filename, int flags, int mode) - { - int namei_flags, error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags }; - - namei_flags = flags; - if ((namei_flags+1) & O_ACCMODE) -@@ -666,14 +693,15 @@ struct file *filp_open(const char * file - if (namei_flags & O_TRUNC) - namei_flags |= 2; - -- error = open_namei(filename, namei_flags, mode, &nd); -- if (!error) -- return dentry_open(nd.dentry, nd.mnt, flags); -+ error = open_namei_it(filename, namei_flags, mode, &nd, &it); -+ if (error) -+ return ERR_PTR(error); - -- return ERR_PTR(error); -+ return dentry_open_it(nd.dentry, nd.mnt, flags, &it); - } - --struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it) - { - struct file * f; - struct inode *inode; -@@ -716,6 +744,7 @@ struct file *dentry_open(struct dentry * - } - f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); - -+ intent_release(dentry, it); - return f; - - cleanup_all: -@@ -730,11 +759,17 @@ cleanup_all: - cleanup_file: - put_filp(f); - cleanup_dentry: -+ intent_release(dentry, it); - dput(dentry); - mntput(mnt); - return ERR_PTR(error); - } - -+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+{ -+ return dentry_open_it(dentry, mnt, flags, NULL); -+} -+ - /* - * Find an empty file descriptor entry, and mark it busy. - */ ---- linux-2.4.19-hp2_pnnl4/fs/stat.c~vfs_intent_hp Sun Jan 19 19:04:47 2003 -+++ linux-2.4.19-hp2_pnnl4-root/fs/stat.c Sun Jan 19 19:44:51 2003 -@@ -135,13 +136,15 @@ static int cp_new_stat(struct inode * in - asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -151,13 +154,15 @@ asmlinkage long sys_stat(char * filename - asmlinkage long sys_newstat(char * filename, struct stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -172,13 +177,15 @@ asmlinkage long sys_newstat(char * filen - asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -189,13 +196,15 @@ asmlinkage long sys_lstat(char * filenam - asmlinkage long sys_newlstat(char * filename, struct stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -333,12 +344,14 @@ asmlinkage long sys_stat64(char * filena - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; -@@ -348,12 +361,14 @@ asmlinkage long sys_lstat64(char * filen - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(nd.dentry, &it); - path_release(&nd); - } - return error; ---- linux-2.4.19-hp2_pnnl4/fs/exec.c~vfs_intent_hp Sun Feb 9 01:14:52 2003 -+++ linux-2.4.19-hp2_pnnl4-root/fs/exec.c Sun Feb 9 01:29:49 2003 -@@ -103,13 +104,18 @@ static inline void put_binfmt(struct lin - * - * Also note that we take the address to load from from the file itself. - */ -+extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it); -+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it); - asmlinkage long sys_uselib(const char * library) - { - struct file * file; - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY }; - -- error = user_path_walk(library, &nd); -+ error = user_path_walk_it(library, &nd, &it); - if (error) - goto out; - -@@ -121,7 +127,8 @@ asmlinkage long sys_uselib(const char * - if (error) - goto exit; - -- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); -+ file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it); -+ intent_release(nd.dentry, &it); - error = PTR_ERR(file); - if (IS_ERR(file)) - goto out; -@@ -350,9 +350,10 @@ struct file *open_exec(const char *name) - struct inode *inode; - struct file *file; - int err = 0; -+ struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY }; - - if (path_init(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd)) -- err = path_walk(name, &nd); -+ err = path_walk_it(name, &nd, &it); - file = ERR_PTR(err); - if (!err) { - inode = nd.dentry->d_inode; -@@ -363,7 +369,8 @@ struct file *open_exec(const char *name) - err = -EACCES; - file = ERR_PTR(err); - if (!err) { -- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); -+ file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it); -+ intent_release(nd.dentry, &it); - if (!IS_ERR(file)) { - err = deny_write_access(file); - if (err) { -@@ -976,7 +986,7 @@ int do_coredump(long signr, struct pt_re - goto close_fail; - if (!file->f_op->write) - goto close_fail; -- if (do_truncate(file->f_dentry, 0) != 0) -+ if (do_truncate(file->f_dentry, 0, 0) != 0) - goto close_fail; - - retval = binfmt->core_dump(signr, regs, file); ---- linux-2.4.19-hp2_pnnl4/include/linux/dcache.h~vfs_intent_hp Sun Jan 19 19:04:47 2003 -+++ linux-2.4.19-hp2_pnnl4-root/include/linux/dcache.h Sun Jan 19 19:04:48 2003 -@@ -6,6 +6,25 @@ - #include - #include - -+#define IT_OPEN (1) -+#define IT_CREAT (1<<1) -+#define IT_READDIR (1<<2) -+#define IT_GETATTR (1<<3) -+#define IT_LOOKUP (1<<4) -+#define IT_UNLINK (1<<5) -+ -+struct lookup_intent { -+ int it_op; -+ int it_mode; -+ int it_flags; -+ int it_disposition; -+ int it_status; -+ struct iattr *it_iattr; -+ __u64 it_lock_handle[2]; -+ int it_lock_mode; -+ void *it_data; -+}; -+ - /* - * linux/include/linux/dcache.h - * -@@ -78,6 +106,7 @@ struct dentry { - unsigned long d_time; /* used by d_revalidate */ - struct dentry_operations *d_op; - struct super_block * d_sb; /* The root of the dentry tree */ -+ struct lookup_intent *d_it; - unsigned long d_vfs_flags; - void * d_fsdata; /* fs-specific data */ - unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */ -@@ -90,8 +119,15 @@ struct dentry_operations { - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); -+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); - }; - -+/* defined in fs/namei.c */ -+extern void intent_release(struct dentry *de, struct lookup_intent *it); -+/* defined in fs/dcache.c */ -+extern void __d_rehash(struct dentry * entry, int lock); -+ - /* the dentry parameter passed to d_hash and d_compare is the parent - * directory of the entries to be compared. It is used in case these - * functions need any directory specific information for determining -@@ -124,6 +149,7 @@ d_iput: no no yes - * s_nfsd_free_path semaphore will be down - */ - #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */ -+#define DCACHE_LUSTRE_INVALID 0x0010 /* Lustre invalidated */ - - extern spinlock_t dcache_lock; - ---- linux-2.4.19-hp2_pnnl4/include/linux/fs.h~vfs_intent_hp Sun Jan 19 19:04:47 2003 -+++ linux-2.4.19-hp2_pnnl4-root/include/linux/fs.h Sun Jan 19 19:04:48 2003 -@@ -338,6 +338,8 @@ extern void set_bh_page(struct buffer_he - #define ATTR_MTIME_SET 256 - #define ATTR_FORCE 512 /* Not a change, but a change it */ - #define ATTR_ATTR_FLAG 1024 -+#define ATTR_RAW 2048 /* file system, not vfs will massage attrs */ -+#define ATTR_FROM_OPEN 4096 /* called from open path, ie O_TRUNC */ - - /* - * This is the Inode Attributes structure, used for notify_change(). It -@@ -575,6 +575,7 @@ struct file { - - /* needed for tty driver, and maybe others */ - void *private_data; -+ struct lookup_intent *f_intent; - - /* preallocated helper kiobuf to speedup O_DIRECT */ - struct kiobuf *f_iobuf; -@@ -815,7 +816,9 @@ extern int vfs_symlink(struct inode *, s - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct lookup_intent *it); - - /* - * File types -@@ -876,20 +879,33 @@ struct file_operations { - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *); - int (*link) (struct dentry *,struct inode *,struct dentry *); -+ int (*link2) (struct inode *,struct inode *, const char *, int); - int (*unlink) (struct inode *,struct dentry *); -+ int (*unlink2) (struct inode *, const char *, int); - int (*symlink) (struct inode *,struct dentry *,const char *); -+ int (*symlink2) (struct inode *, const char *, int, const char *); - int (*mkdir) (struct inode *,struct dentry *,int); -+ int (*mkdir2) (struct inode *, const char *, int,int); - int (*rmdir) (struct inode *,struct dentry *); -+ int (*rmdir2) (struct inode *, const char *, int); - int (*mknod) (struct inode *,struct dentry *,int,int); -+ int (*mknod2) (struct inode *, const char *, int,int,int); - int (*rename) (struct inode *, struct dentry *, - struct inode *, struct dentry *); -+ int (*rename2) (struct inode *, struct inode *, -+ const char *oldname, int oldlen, -+ const char *newname, int newlen); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); -+ int (*follow_link2) (struct dentry *, struct nameidata *, -+ struct lookup_intent *it); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*revalidate) (struct dentry *); - int (*setattr) (struct dentry *, struct iattr *); -+ int (*setattr_raw) (struct inode *, struct iattr *); - int (*getattr) (struct dentry *, struct iattr *); - int (*setxattr) (struct dentry *, const char *, void *, size_t, int); - ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); -@@ -1112,7 +1130,7 @@ static inline int get_lease(struct inode - - asmlinkage long sys_open(const char *, int, int); - asmlinkage long sys_close(unsigned int); /* yes, it's really unsigned */ --extern int do_truncate(struct dentry *, loff_t start); -+extern int do_truncate(struct dentry *, loff_t start, int called_from_open); - - extern struct file *filp_open(const char *, int, int); - extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); -@@ -1354,6 +1369,7 @@ typedef int (*read_actor_t)(read_descrip - extern loff_t default_llseek(struct file *file, loff_t offset, int origin); - - extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *)); -+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it)); - extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *)); - extern int FASTCALL(path_walk(const char *, struct nameidata *)); - extern int FASTCALL(link_path_walk(const char *, struct nameidata *)); -@@ -1364,6 +1380,8 @@ extern struct dentry * lookup_one_len(co - extern struct dentry * lookup_hash(struct qstr *, struct dentry *); - #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) - #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) -+#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it) -+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it) - - extern void inode_init_once(struct inode *); - extern void iput(struct inode *); -@@ -1499,6 +1517,8 @@ extern struct file_operations generic_ro - - extern int vfs_readlink(struct dentry *, char *, int, const char *); - extern int vfs_follow_link(struct nameidata *, const char *); -+extern int vfs_follow_link_it(struct nameidata *, const char *, -+ struct lookup_intent *it); - extern int page_readlink(struct dentry *, char *, int); - extern int page_follow_link(struct dentry *, struct nameidata *); - extern struct inode_operations page_symlink_inode_operations; ---- linux-2.4.19-hp2_pnnl4/kernel/ksyms.c~vfs_intent_hp Sun Jan 19 19:04:47 2003 -+++ linux-2.4.19-hp2_pnnl4-root/kernel/ksyms.c Sun Jan 19 19:04:48 2003 -@@ -293,6 +293,7 @@ EXPORT_SYMBOL(read_cache_page); - EXPORT_SYMBOL(set_page_dirty); - EXPORT_SYMBOL(vfs_readlink); - EXPORT_SYMBOL(vfs_follow_link); -+EXPORT_SYMBOL(vfs_follow_link_it); - EXPORT_SYMBOL(page_readlink); - EXPORT_SYMBOL(page_follow_link); - EXPORT_SYMBOL(page_symlink_inode_operations); diff --git a/lustre/kernel_patches/pc/dev_read_only.pc b/lustre/kernel_patches/pc/dev_read_only.pc deleted file mode 100644 index 4760ad1..0000000 --- a/lustre/kernel_patches/pc/dev_read_only.pc +++ /dev/null @@ -1,3 +0,0 @@ -drivers/block/blkpg.c -drivers/block/loop.c -drivers/ide/ide-disk.c diff --git a/lustre/kernel_patches/pc/dev_read_only_hp.pc b/lustre/kernel_patches/pc/dev_read_only_hp.pc deleted file mode 100644 index 4760ad1..0000000 --- a/lustre/kernel_patches/pc/dev_read_only_hp.pc +++ /dev/null @@ -1,3 +0,0 @@ -drivers/block/blkpg.c -drivers/block/loop.c -drivers/ide/ide-disk.c diff --git a/lustre/kernel_patches/pc/exports.pc b/lustre/kernel_patches/pc/exports.pc deleted file mode 100644 index 6472a11..0000000 --- a/lustre/kernel_patches/pc/exports.pc +++ /dev/null @@ -1,4 +0,0 @@ -fs/ext3/Makefile -fs/ext3/super.c -include/linux/fs.h -kernel/ksyms.c diff --git a/lustre/kernel_patches/pc/exports_hp.pc b/lustre/kernel_patches/pc/exports_hp.pc deleted file mode 100644 index 6472a11..0000000 --- a/lustre/kernel_patches/pc/exports_hp.pc +++ /dev/null @@ -1,4 +0,0 @@ -fs/ext3/Makefile -fs/ext3/super.c -include/linux/fs.h -kernel/ksyms.c diff --git a/lustre/kernel_patches/pc/invalidate_show.pc b/lustre/kernel_patches/pc/invalidate_show.pc deleted file mode 100644 index 1f565ab..0000000 --- a/lustre/kernel_patches/pc/invalidate_show.pc +++ /dev/null @@ -1,5 +0,0 @@ -fs/inode.c -fs/block_dev.c -fs/devfs/base.c -fs/super.c -include/linux/fs.h diff --git a/lustre/kernel_patches/pc/iod-rmap-exports.pc b/lustre/kernel_patches/pc/iod-rmap-exports.pc deleted file mode 100644 index 1218f55..0000000 --- a/lustre/kernel_patches/pc/iod-rmap-exports.pc +++ /dev/null @@ -1,6 +0,0 @@ -fs/inode.c -fs/Makefile -mm/filemap.c -mm/vmscan.c -mm/Makefile -mm/page_alloc.c diff --git a/lustre/kernel_patches/pc/jbd-transno-cb.pc b/lustre/kernel_patches/pc/jbd-transno-cb.pc deleted file mode 100644 index cde73d8..0000000 --- a/lustre/kernel_patches/pc/jbd-transno-cb.pc +++ /dev/null @@ -1,4 +0,0 @@ -fs/jbd/commit.c -fs/jbd/journal.c -fs/jbd/transaction.c -include/linux/jbd.h diff --git a/lustre/kernel_patches/pc/kmem_cache_validate.pc b/lustre/kernel_patches/pc/kmem_cache_validate.pc deleted file mode 100644 index a0a6297..0000000 --- a/lustre/kernel_patches/pc/kmem_cache_validate.pc +++ /dev/null @@ -1,5 +0,0 @@ -arch/i386/mm/init.c -arch/ia64/mm/init.c -include/linux/slab.h -kernel/ksyms.c -mm/slab.c diff --git a/lustre/kernel_patches/pc/kmem_cache_validate_hp.pc b/lustre/kernel_patches/pc/kmem_cache_validate_hp.pc deleted file mode 100644 index a0a6297..0000000 --- a/lustre/kernel_patches/pc/kmem_cache_validate_hp.pc +++ /dev/null @@ -1,5 +0,0 @@ -arch/i386/mm/init.c -arch/ia64/mm/init.c -include/linux/slab.h -kernel/ksyms.c -mm/slab.c diff --git a/lustre/kernel_patches/pc/lustre-2.5.pc b/lustre/kernel_patches/pc/lustre-2.5.pc deleted file mode 100644 index 71434ea..0000000 --- a/lustre/kernel_patches/pc/lustre-2.5.pc +++ /dev/null @@ -1,11 +0,0 @@ -arch/um/kernel/mem.c -fs/namei.c -fs/nfsd/vfs.c -fs/sysfs/inode.c -include/linux/dcache.h -include/linux/fs.h -include/linux/namei.h -include/linux/slab.h -kernel/ksyms.c -mm/slab.c -net/unix/af_unix.c diff --git a/lustre/kernel_patches/pc/lustre_version.pc b/lustre/kernel_patches/pc/lustre_version.pc deleted file mode 100644 index 898bebd..0000000 --- a/lustre/kernel_patches/pc/lustre_version.pc +++ /dev/null @@ -1 +0,0 @@ -include/linux/lustre_version.h diff --git a/lustre/kernel_patches/pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc b/lustre/kernel_patches/pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc deleted file mode 100644 index 44d4abf..0000000 --- a/lustre/kernel_patches/pc/patch-2.4.18-hp1_pnnl18.2.8qsnet.pc +++ /dev/null @@ -1,23 +0,0 @@ -./include/linux/lustre_version.h -./arch/ia64/mm/init.c -./arch/i386/mm/init.c -./drivers/block/blkpg.c -./drivers/block/loop.c -./drivers/ide/ide-disk.c -./fs/ext3/Makefile -./fs/ext3/super.c -./fs/jbd/commit.c -./fs/jbd/journal.c -./fs/jbd/transaction.c -./include/linux/blkdev.h -./include/linux/slab.h -./include/linux/jbd.h -./kernel/ksyms.c -./include/linux/dcache.h -./include/linux/fs.h -./fs/dcache.c -./fs/nfsd/vfs.c -./fs/namei.c -./fs/open.c -./fs/stat.c -./mm/slab.c diff --git a/lustre/kernel_patches/pc/uml_check_get_page.pc b/lustre/kernel_patches/pc/uml_check_get_page.pc deleted file mode 100644 index 3dbf042..0000000 --- a/lustre/kernel_patches/pc/uml_check_get_page.pc +++ /dev/null @@ -1,2 +0,0 @@ -arch/um/kernel/mem.c -arch/um/kernel/mem.c.uml-fixes diff --git a/lustre/kernel_patches/pc/uml_compile_fixes.pc b/lustre/kernel_patches/pc/uml_compile_fixes.pc deleted file mode 100644 index c1caa12..0000000 --- a/lustre/kernel_patches/pc/uml_compile_fixes.pc +++ /dev/null @@ -1,2 +0,0 @@ -include/asm-um/pgtable.h -include/asm-um/pgtable.h.orig diff --git a/lustre/kernel_patches/pc/uml_no_panic.pc b/lustre/kernel_patches/pc/uml_no_panic.pc deleted file mode 100644 index 3dbf042..0000000 --- a/lustre/kernel_patches/pc/uml_no_panic.pc +++ /dev/null @@ -1,2 +0,0 @@ -arch/um/kernel/mem.c -arch/um/kernel/mem.c.uml-fixes diff --git a/lustre/kernel_patches/pc/vanilla-2.4.18.pc b/lustre/kernel_patches/pc/vanilla-2.4.18.pc deleted file mode 100644 index c1ed719..0000000 --- a/lustre/kernel_patches/pc/vanilla-2.4.18.pc +++ /dev/null @@ -1,23 +0,0 @@ -include/linux/lustre_version.h -arch/ia64/mm/init.c -arch/i386/mm/init.c -drivers/block/blkpg.c -drivers/block/loop.c -drivers/ide/ide-disk.c -fs/ext3/Makefile -fs/ext3/super.c -fs/jbd/commit.c -fs/jbd/journal.c -fs/jbd/transaction.c -include/linux/blkdev.h -include/linux/slab.h -include/linux/jbd.h -kernel/ksyms.c -include/linux/dcache.h -include/linux/fs.h -fs/dcache.c -fs/nfsd/vfs.c -fs/namei.c -fs/open.c -fs/stat.c -mm/slab.c diff --git a/lustre/kernel_patches/pc/vanilla-2.4.19.pc b/lustre/kernel_patches/pc/vanilla-2.4.19.pc deleted file mode 100644 index bb5c390..0000000 --- a/lustre/kernel_patches/pc/vanilla-2.4.19.pc +++ /dev/null @@ -1,19 +0,0 @@ -include/linux/lustre_version.h -arch/ia64/mm/init.c -arch/i386/mm/init.c -drivers/block/blkpg.c -drivers/block/loop.c -drivers/ide/ide-disk.c -fs/ext3/Makefile -fs/ext3/super.c -include/linux/blkdev.h -include/linux/slab.h -kernel/ksyms.c -include/linux/dcache.h -include/linux/fs.h -fs/dcache.c -fs/nfsd/vfs.c -fs/namei.c -fs/open.c -fs/stat.c -mm/slab.c diff --git a/lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc b/lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc deleted file mode 100644 index dd2b1c8..0000000 --- a/lustre/kernel_patches/pc/vfs_intent-2.4.18-18.pc +++ /dev/null @@ -1,9 +0,0 @@ -fs/dcache.c -fs/namei.c -fs/nfsd/vfs.c -fs/open.c -fs/stat.c -fs/exec.c -include/linux/dcache.h -include/linux/fs.h -kernel/ksyms.c diff --git a/lustre/kernel_patches/pc/vfs_intent.pc b/lustre/kernel_patches/pc/vfs_intent.pc deleted file mode 100644 index 881576c..0000000 --- a/lustre/kernel_patches/pc/vfs_intent.pc +++ /dev/null @@ -1,8 +0,0 @@ -fs/dcache.c -fs/namei.c -fs/nfsd/vfs.c -fs/open.c -fs/stat.c -include/linux/dcache.h -include/linux/fs.h -kernel/ksyms.c diff --git a/lustre/kernel_patches/pc/vfs_intent_hp.pc b/lustre/kernel_patches/pc/vfs_intent_hp.pc deleted file mode 100644 index 881576c..0000000 --- a/lustre/kernel_patches/pc/vfs_intent_hp.pc +++ /dev/null @@ -1,8 +0,0 @@ -fs/dcache.c -fs/namei.c -fs/nfsd/vfs.c -fs/open.c -fs/stat.c -include/linux/dcache.h -include/linux/fs.h -kernel/ksyms.c diff --git a/lustre/kernel_patches/prepare_tree.sh b/lustre/kernel_patches/prepare_tree.sh deleted file mode 100755 index f512132..0000000 --- a/lustre/kernel_patches/prepare_tree.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/bash - -die() { - echo -e $* >&2 - echo aborting.. >&2 - exit 1 -} - -canon() { - cd $1 - CANON=$PWD - cd - -} - -canon $(dirname $0) -MYDIR=$CANON - -while [ ${#*} -gt 1 ]; do - case "$1" in - -t) - shift; - TREE=$1 - ;; - -s) - shift; - SERIES=$1 - ;; - *) - die "unknown argument $1" - break; - ;; - esac - shift; -done - -[ -z "$TREE" -o -z "$SERIES" ] && die "I need a tree and series:\n\t$0 -t kernel_dir -s series_name" -[ ! -d $TREE ] && die "kernel tree '$TREE' isn't a directory" -SERIES=$(basename $SERIES) -[ ! -f $MYDIR/series/$SERIES ] && die "no series file '$SERIES'" - -canon $TREE -TREE=$CANON - -# patch scripts wants a relative path from the linux tree to -# its patch pile :( - -MY=$(echo $MYDIR | sed -e 's_^/__') -TR=$(echo $TREE | sed -e 's_^/__') - -while true ; do - M=$(echo $MY | cut -d/ -f 1) - T=$(echo $TR | cut -d/ -f 1) - - if [ $M != $T ]; then - break; - fi - - MY=$(echo $MY | cut -d/ -f 2-) - TR=$(echo $TR | cut -d/ -f 2-) -done - -[ $MY == $MYDIR ] && die "bad! $MY == $MYDIR" - -REVERSE=$(revpath $TR)${MY} -ABSINO=$(stat $MYDIR | awk '($3 == "Inode:") {print $4}') -REVINO=`(cd $TREE ; stat $REVERSE | awk '($3 == "Inode:") {print $4}')` - -[ $ABSINO != $REVINO ] && die "inodes differ, my reverse path is bad?" - -echo export PATCHSCRIPTS=$REVERSE - -cd $TREE -ln -sf $REVERSE/series/$SERIES series - -PATH_ELEMENTS=$(echo $PATH | sed -e 's/:/ /g') - -NEW_PATH=$MYDIR/scripts - -for p in $PATH_ELEMENTS; do - if echo $p | grep kernel_patches/scripts > /dev/null 2>&1 ; then - continue; - fi - NEW_PATH="$NEW_PATH:$p" -done - -echo export PATH=$NEW_PATH - -echo "'$TREE' successfully setup" >&2 diff --git a/lustre/kernel_patches/scripts/added-by-patch b/lustre/kernel_patches/scripts/added-by-patch deleted file mode 100755 index e9ccef6..0000000 --- a/lustre/kernel_patches/scripts/added-by-patch +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# Extract names of new files from a patch, print them out - -PATCHFILE=$1 -case "$PATCHFILE" in -*.gz) CMD="gzip -d < $PATCHFILE";; -*) CMD="cat $PATCHFILE";; -esac - -TMP=$(mktemp /tmp/abp.XXXXXX) - -eval $CMD | egrep '^--- .*1969|^--- .*1970' > $TMP -sed -e 's@[^/]*/\([^ ]*\).*@\1@' < $TMP | sed -e 's@^linux/@@' | sort -rm -f $TMP diff --git a/lustre/kernel_patches/scripts/apatch b/lustre/kernel_patches/scripts/apatch deleted file mode 100755 index 4b63598..0000000 --- a/lustre/kernel_patches/scripts/apatch +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - - -do_apply() -{ - FILES=$(cat $P/pc/$PATCH_NAME.pc) - for file in $FILES - do - copy_file_to_bup $file $PATCH_NAME - done - - silent=-s - if [ $opt_force != 0 ] - then - silent= - fi - - if patch -p1 $silent -i "$1" || [ $opt_force != 0 ] - then - true - else - echo SOMETHING WENT WRONG - exit 1 - fi -} - -add_to_db() -{ - basename "$1" >> "$DB" -} - -usage() -{ - echo "Usage: apatch patchname" - exit 1 -} - -opt_force=0 -PATCH_NAMES="" - -for i in $* -do - case "$i" in - -f) - opt_force=1;; - *) - PATCH_NAMES="$PATCH_NAMES $i" - esac -done - -if [ x"$PATCH_NAMES" == x ] -then - usage -fi - -apatch() -{ - PATCH_NAME=$(stripit $1) - - need_file_there $P/pc/$PATCH_NAME.pc - - if is_applied "$PATCH_NAME" - then - echo "$PATCH_NAME" is already applied - exit 1 - fi - - if [ $opt_force != 0 ] - then - echo FORCING PATCH - fi - - if [ $opt_force != 0 ] || can_apply $P/patches/"$PATCH_NAME".patch - then - do_apply $P/patches/"$PATCH_NAME".patch - add_to_db "$PATCH_NAME" - echo applied $PATCH_NAME - echo - else - echo "$PATCH_NAME" does not apply - exit 1 - fi -} - -for i in $PATCH_NAMES -do - if ! apatch $i - then - exit 1 - fi -done - diff --git a/lustre/kernel_patches/scripts/combine-applied b/lustre/kernel_patches/scripts/combine-applied deleted file mode 100755 index 8768b29..0000000 --- a/lustre/kernel_patches/scripts/combine-applied +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -# -# Make superpatch from currently applied patches using combinediff. -# - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: combine-applied output-file" - exit 1 -} - -if [ $# -ne 1 ] -then - usage -fi - -need_file_there applied-patches -CURRENT=$(mktemp /tmp/cmbd-XXXXXXXX) -for FILE in `cat applied-patches` -do - NEXT=$(mktemp /tmp/cmbd-XXXXXXXX) - if [ -f $P/patches/$FILE ] - then - combinediff $CURRENT $P/patches/$FILE > $NEXT - elif [ -f $P/patches/$FILE.patch ] - then - combinediff $CURRENT $P/patches/$FILE.patch > $NEXT - elif [ -f $FILE ] - then - combinediff $CURRENT $FILE > $NEXT - fi - rm $CURRENT - CURRENT=$NEXT -done - -mv $NEXT "$1" diff --git a/lustre/kernel_patches/scripts/combine-series b/lustre/kernel_patches/scripts/combine-series deleted file mode 100755 index d00ba36..0000000 --- a/lustre/kernel_patches/scripts/combine-series +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -# -# Make superpatch from current series using combinediff. -# - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: combine-series output-file" - exit 1 -} - -if [ $# -ne 1 ] -then - usage -fi - -need_file_there series -CURRENT=$(mktemp /tmp/cmbd-XXXXXXXX) -for FILE in $(cat series) -do - NEXT=$(mktemp /tmp/cmbd-XXXXXXXX) - if [ -f $P/patches/$FILE ] - then - combinediff $CURRENT $P/patches/$FILE > $NEXT - elif [ -f $P/patches/$FILE.patch ] - then - combinediff $CURRENT $P/patches/$FILE.patch > $NEXT - elif [ -f $FILE ] - then - combinediff $CURRENT $FILE > $NEXT - fi - rm $CURRENT - CURRENT=$NEXT -done - -mv $NEXT "$1" diff --git a/lustre/kernel_patches/scripts/cvs-take-patch b/lustre/kernel_patches/scripts/cvs-take-patch deleted file mode 100755 index c6a6a2a..0000000 --- a/lustre/kernel_patches/scripts/cvs-take-patch +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/sh - -doit() -{ - echo $* - $* -} - -usage() -{ - echo "Usage: cvs-take-patch patch_file_name" - exit 1 -} - -# -# Find the highest level directory in $1 which does not -# contain the directory $2. Return it in $MISSING -# -highest_missing() -{ - START_DIR="$1" - NAME="$2" - MISSING="" - WHERE=$(dirname "$START_DIR") - PREV_WHERE=$START_DIR - while [ x"$WHERE" != x"$PREV_WHERE" ] - do - WHERE="$PREV_WHERE" - if [ ! -d "$WHERE"/"$NAME" ] - then - MISSING="$WHERE" - fi - PREV_WHERE=$(dirname "$WHERE") - done - echo highest_missing returns $MISSING -} - -# -# Add all new directries to CVS, top-down -# $1: name of a directory -# $2: name of the CVS directory -# -add_cvs_dirs() -{ - MISSING=foo - while [ "$MISSING" != "" ] - do - highest_missing $1 $2 - if [ x"$MISSING" != "x" ] - then - if [ ! -d "$MISSING"/"$2" ] - then - doit cvs add $MISSING - fi - fi - done -} - -PATCHFILE=$1 - -REMOVEDFILES=$(removed-by-patch $PATCHFILE) -if [ "$REMOVEDFILES" != "" ] -then - doit cvs remove $REMOVEDFILES -fi - -NEWFILES=$(added-by-patch $PATCHFILE) -for i in $NEWFILES -do - DIRNAME=$(dirname $i) - echo "Looking at $DIRNAME" - add_cvs_dirs $DIRNAME CVS -done - -if [ "$NEWFILES" != "" ] -then - doit cvs add $NEWFILES -fi diff --git a/lustre/kernel_patches/scripts/export_patch b/lustre/kernel_patches/scripts/export_patch deleted file mode 100755 index d378417..0000000 --- a/lustre/kernel_patches/scripts/export_patch +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "export_patch: export the patches listed in ./series" 1>&2 - echo "usage: export_patch destination-directory [prefix] " 1>&2 - exit 1 -} - -DIR="$1" -PREFIX="$2""_" - -if [ "$DIR" = "" ] -then - usage -fi - -if [ -e "$DIR" -a ! -d "$DIR" ] -then - echo "$DIR exists already, but is not a directory." 1>&2 - exit 1 -fi - -if [ ! -r ./series ] -then - echo "./series is not readable." 1>&2 - exit 1 -fi - -mkdir -p "$DIR" || exit 1 - -count=1 -for x in `cat ./series` -do - fname=`echo "$count" "$PREFIX" "$x" |\ - awk '{ if ( $2 != "_" ) - printf("p%05d_%s%s\n", $1, $2, $3); - else - printf("p%05d_%s\n", $1, $3); - }'` - if [ ! -r $P/patches/"$x" ] - then - echo "$P/patches/"$x" is not readable. skipping." 1>&2 - continue; - fi - cp -f $P/patches/"$x" "$DIR"/"$fname" || continue; - count=`expr $count + 1` -done - diff --git a/lustre/kernel_patches/scripts/extract_description b/lustre/kernel_patches/scripts/extract_description deleted file mode 100755 index 6fa0e68..0000000 --- a/lustre/kernel_patches/scripts/extract_description +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/sh - -insert_line() -{ - PATTERN="$1" - LINE="$2" - FILE="$3" - awk ' BEGIN { found=0; } - /'"$PATTERN"'/ { - print; - if (!found) - printf("%s\n", "'$LINE'"); - found=1; - next; - } - { print; } - ' < "$FILE" -} - -# extract the description from the top of a patch -# filter stdin -# collapse adjacent blank lines to a single blank line -# remove any lines that look like diffstat output -# stop output on encountering a line beginning with '---' (beginning of patch) - - TMPFILE=`mktemp /tmp/xdtmp.XXXXXX` || exit 1 - formail -kfcb -X 'From:' -X 'Subject:' |\ - awk ' - BEGIN { found_end=0; lastone="x"; } - /^ .* [|] +[0-9]+ [+-]+$/ { - #/* we found something like diffstat output... */ - if (found_end == 1) { - /* we are past end of diffstat, let it pass */ - print; - } - next; - } - /^ [1-9][0-9]* files changed/ { - #/* end of diffstat output, stop filtering diffstat */ - found_end=1; - next; - } - /^--- / { exit; } - { - #/* collapse adjacent blank lines to 1 blank line */ - if ( $0 == "" && lastone == "" ) - next; - else - print; - lastone=$0; - } - ' | awk '{ if ($0 == "" && FNR == 1) next; print; }' > "$TMPFILE" - - descs=`head -10 $TMPFILE | grep -c '^[ ]*DESC[ ]*$'` - if [ "$descs" = "0" ] - then - # DESC is not 1st non blank line in the file - echo "DESC" - descs=0 - fi - edescs=`grep -c '^EDESC$' "$TMPFILE"` - subjects=`grep -c '^[ ]*Subject[:]' "$TMPFILE"` - froms=`grep -c '^[ ]*From[:]' "$TMPFILE"` - if [ "$edescs" = "0" ] - then - if [ "$subjects" != "0" ] - then - insert_line '^Subject[:]' 'EDESC' "$TMPFILE" - else - if [ "$froms" != "0" ] - then - insert_line '^From[:]' 'EDESC' "$TMPFILE" - else - if [ "$descs" = "0" ] - then - # blank DESC line... - echo '(undescribed patch)' - echo EDESC - cat "$TMPFILE" - else - insert_line '^DESC$' "EDESC" "$TMPFILE" - fi - fi - fi - else - cat $TMPFILE - fi diff --git a/lustre/kernel_patches/scripts/fpatch b/lustre/kernel_patches/scripts/fpatch deleted file mode 100755 index 0cafa65..0000000 --- a/lustre/kernel_patches/scripts/fpatch +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh - -# -# Add a file to a patch. -# - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: fpatch patchname filename" - echo " fpatch filename" - exit 1 -} - -if [ $# == 1 ] -then - PATCH_NAME=$(top_patch) - FILENAME=$1 -elif [ $# == 2 ] -then - PATCH_NAME=$(stripit $1) - FILENAME=$2 -else - usage -fi - - -if is_applied_last $PATCH_NAME -then - true -else - if is_applied $PATCH_NAME - then - echo $PATCH_NAME is not the last-applied patch - exit 1 - else - echo $PATCH_NAME >> $DB - fi -fi - -if file_in_patch $FILENAME $PATCH_NAME -then - echo File $FILENAME is already in patch $PATCH_NAME - exit 1 -fi - -install_file_in_patch $FILENAME $PATCH_NAME - diff --git a/lustre/kernel_patches/scripts/import_patch b/lustre/kernel_patches/scripts/import_patch deleted file mode 100755 index f818f19..0000000 --- a/lustre/kernel_patches/scripts/import_patch +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "usage: import_patch [ -p prefix-pattern ] patchfile [...]" 1>&2 - exit 1 -} - -XPATTERN="" -if [ "$1" = "-p" ] -then - XPATTERN="$2" - shift; - shift; -fi - -if [ "$1" = "" ] -then - usage -fi - -if [ ! -e applied-patches ] -then - touch applied-patches -fi - -mkdir -p patches || exit 1 -mkdir -p txt || exit 1 -mkdir -p pc || exit 1 - -if [ ! -e ./series ] -then - touch ./series - if [ "$?" != "0" ] - then - echo "Cannot create ./series" 1>&2 - exit 1 - fi -fi - -if [ ! -w ./series ] -then - echo "./series is not writable." 1>&2 - exit 1 -fi - -PATTERN='s/^'"$XPATTERN"'//' -for x in $* -do - if [ ! -r "$x" ] - then - echo "$x does not exist, skipping." 1>&2 - continue - fi - patchname=`basename $x .bz2` - patchname=`basename $patchname .gz` - patchname=`basename $patchname .Z` - patchname=`basename $patchname .patch` - if is_applied $patchname - then - echo $patchname is currently applied - exit 1 - fi - if [ "$XPATTERN" != "" ] - then - patchname=`echo $patchname | sed -e "$PATTERN"` - fi - pname=$P/patches/"$patchname".patch - if [ -r "$pname" ] - then - echo "$pname exists already, skipping." 1>&2 - continue - fi - case "$x" in - *.bz2) - bunzip2 < "$x" > "$pname" - ;; - *.gz) - gunzip < "$x" > "$pname" - ;; - *.Z) zcat < "$z" > "$pname" - ;; - *) - cat "$x" > "$pname" || continue - ;; - esac - echo "$patchname".patch >> series - pcpatch "$pname" - extract_description < "$pname" >$P/txt/"$patchname".txt - grep '^[(]undescribed patch[)]$' < $P/txt/"$patchname".txt > /dev/null - if [ "$?" = "0" ] - then - echo "Warning: $patchname has no description." 1>&2 - fi -done - diff --git a/lustre/kernel_patches/scripts/inpatch b/lustre/kernel_patches/scripts/inpatch deleted file mode 100755 index edb2c20..0000000 --- a/lustre/kernel_patches/scripts/inpatch +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: inpatch" - exit 1 -} - -if [ $# != 0 ] -then - usage -fi - -if [ -e $DB ] -then - TOP_PATCH=$(top_patch) - if [ x$TOP_PATCH != x ] - then - cat $P/pc/$TOP_PATCH.pc - fi -fi diff --git a/lustre/kernel_patches/scripts/linus-patch b/lustre/kernel_patches/scripts/linus-patch deleted file mode 100755 index 290b9cf..0000000 --- a/lustre/kernel_patches/scripts/linus-patch +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -# -# Grab a patch frmo kernel.org, install it. -# -# Usage: linus-patch http://www.kernel.org/pub/linux/kernel/people/dwmw2/bk-2.5/cset-1.786.152.7-to-1.798.txt.gz -# - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -poppatch 999 || die poppatch -wget $1 || die wget -FILE=$(basename $1) -gzip -d < $FILE > $P/patches/linus.patch -pcpatch linus || die pcpatch -( - echo DESC - echo $FILE - echo EDESC - echo - echo $FILE -) > $P/txt/linus.txt -rm $FILE diff --git a/lustre/kernel_patches/scripts/mpatch b/lustre/kernel_patches/scripts/mpatch deleted file mode 100755 index 16d4eb7..0000000 --- a/lustre/kernel_patches/scripts/mpatch +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: mpatch patchname [output_dir]" - exit 1 -} - -doit() -{ - echo $* 1>&2 - $* || { - echo oops - exit 1 - } -} - -epoch() -{ -# doit touch -t 7001011000.00 $1 - doit touch -t 7001010000.00 $1 -} - -dirfor() -{ - dir=$(dirname $1) - if [ ! -d $dir ] - then - doit mkdir -p $dir - RMDIRS="$RMDIRS $dir" - fi -} - -if [ $# == 0 ] -then - usage -fi - -PATCH_NAME=$(stripit $1) -OUTPUT_DIR=$2 - -FILES=$(cat $P/pc/$PATCH_NAME.pc) -OUT=$P/patches/$PATCH_NAME.patch -TMPOUT=$(mktemp /tmp/patch-$PATCH_NAME-XXXXXX) -TXT=$P/txt/$PATCH_NAME.txt -OLDDIR=$(basename $(/bin/pwd)) -NEWDIR=$OLDDIR-$LOGNAME - -if is_applied_last $PATCH_NAME -then - true -else - echo $PATCH_NAME is not the last-applied patch - exit 1 -fi - -doit rm -f $OUT -echo "Placing patch in " $OUT - -if [ -e $TXT -a -s $TXT ] -then - echo >> $OUT - body $TXT >> $OUT - echo >> $OUT - echo >> $OUT -else - echo "**** No patch description for $PATCH_NAME ****" -fi - -rm -f $TMPOUT - -for file in $FILES -do - OLD_FILE="$file"~"$PATCH_NAME" - if [ ! -e $OLD_FILE ] - then - OLD_FILE=/dev/null - fi - NEW_FILE=$file - XDIFF_OPTS="" - if [ ! -e $NEW_FILE ] - then - NEW_FILE=/dev/null - XDIFF_OPTS="-L $file" - fi - - echo diff -puN $XDIFF_OPTS $DIFF_OPTS $OLD_FILE $NEW_FILE - diff -puN $XDIFF_OPTS $DIFF_OPTS $OLD_FILE $NEW_FILE | p0-2-p1 $OLDDIR $NEWDIR >> $TMPOUT -done -diffstat -p1 $TMPOUT >> $OUT 2>/dev/null -echo >> $OUT -cat $TMPOUT >> $OUT -echo >> $OUT -echo "_" >> $OUT -rm -f $TMPOUT diff --git a/lustre/kernel_patches/scripts/new-kernel b/lustre/kernel_patches/scripts/new-kernel deleted file mode 100755 index 2b065a6..0000000 --- a/lustre/kernel_patches/scripts/new-kernel +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/sh - -usage() -{ - echo "Usage: new-kernel linux-2.4.2-pre2 linux-2.4.3-pre3 linux-2.4.3 patch.gz cvs-dir" - exit 1 -} - -wantdir() -{ - if [ x$1 = x ] - then - usage - fi - if [ ! -d $1 ] - then - echo "directory $1 does not exist" - usage - fi -} - -wantfile() -{ - if [ x$1 = x ] - then - usage - fi - if [ ! -f $1 ] - then - echo "file $1 does not exist" - usage - fi -} - -doit() -{ - echo $* 1>&2 - $* || { - echo oops - exit 1 - } -} - - -CURRENT_KERNEL=$1 -NEXT_KERNEL=$2 -BASE_KERNEL=$3 -PATCH_FILE=$4 -CVS_DIR=$5 - -TEMP_PATCH=$(mktemp /tmp/patch-XXXXXX) -MY_DIFF="$CURRENT_KERNEL"--"$NEXT_KERNEL" - -wantdir $CURRENT_KERNEL -wantdir $BASE_KERNEL -wantdir $CVS_DIR -wantfile $PATCH_FILE - -doit rm -rf $NEXT_KERNEL -doit cp -a $BASE_KERNEL $NEXT_KERNEL -doit rm -f $TEMP_PATCH -doit gunzip < $PATCH_FILE > $TEMP_PATCH -cd $NEXT_KERNEL -doit patch -p1 --dry-run -i $TEMP_PATCH -doit patch -p1 -s -i $TEMP_PATCH -echo cd .. -cd .. - -echo diff -uNrp $CURRENT_KERNEL $NEXT_KERNEL -diff -uNrp $CURRENT_KERNEL $NEXT_KERNEL > $MY_DIFF - -echo cd $CVS_DIR -cd $CVS_DIR -doit patch -p1 --dry-run -s -i ../$MY_DIFF -doit patch -p1 -s -i ../$MY_DIFF -cvs-take-patch ../$MY_DIFF -cvs commit -m "'doing $NEXT_KERNEL'" -cvs update -ko -d -P - -TAG=$(echo $NEXT_KERNEL | sed -e 's@\.@_@g') -cvs tag $TAG -rm -f $TEMP_PATCH diff --git a/lustre/kernel_patches/scripts/p0-2-p1 b/lustre/kernel_patches/scripts/p0-2-p1 deleted file mode 100755 index 266c698..0000000 --- a/lustre/kernel_patches/scripts/p0-2-p1 +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -# -# Usage: p0-2-p1 olddir newdir -# -OLDDIR=$1 -NEWDIR=$2 - -sed -e "s/^--- \([^\/].*\)/--- $OLDDIR\/\1/" | -sed -e "s/^+++ \([^\/].*\)/+++ $NEWDIR\/\1/" - diff --git a/lustre/kernel_patches/scripts/p_diff b/lustre/kernel_patches/scripts/p_diff deleted file mode 100755 index 1ad3e09..0000000 --- a/lustre/kernel_patches/scripts/p_diff +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/sh - -# -# Bring up a patched file in diff. We show the diffs -# in the topmost patch, unless it was specified -# - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: pdiff [patchname] filename" - echo " pdiff [patchname] -" - exit 1 -} - -if [ $# == 1 ] -then - PATCH_NAME=$(top_patch) - FILENAME=$1 -elif [ $# == 2 ] -then - PATCH_NAME=$(stripit $1) - FILENAME=$2 -else - usage -fi - -if ! is_applied $PATCH_NAME -then - echo $PATCH_NAME is not applied - exit 1 -fi - -doit() -{ - filename=$1 - unpatched_file=$filename"~"$PATCH_NAME - need_file_there $filename - if [ -e $unpatched_file ] - then - diff -u $unpatched_file $filename - else - echo pdiff: $filename appears to not be in $PATCH_NAME - fi -} - -if [ x"$FILENAME" = "x-" ] -then - FILENAME=$(cat $P/pc/$PATCH_NAME.pc) -fi - -for i in $FILENAME -do - doit $i -done diff --git a/lustre/kernel_patches/scripts/patchdesc b/lustre/kernel_patches/scripts/patchdesc deleted file mode 100755 index 9a886fd..0000000 --- a/lustre/kernel_patches/scripts/patchdesc +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -desc1() -{ - PATCH=$(stripit $1) - TXT=$P/txt/$PATCH.txt - echo $PATCH.patch - desc < $TXT - echo -} - -for i in $* -do - desc1 $i -done diff --git a/lustre/kernel_patches/scripts/patchfns b/lustre/kernel_patches/scripts/patchfns deleted file mode 100644 index b6cc468..0000000 --- a/lustre/kernel_patches/scripts/patchfns +++ /dev/null @@ -1,239 +0,0 @@ -DB=applied-patches - -# -# Work out where the user's pc/, patch/ and txt/ directories live. -# -# If the user specified PATCHSCRIPTS in environment then use that (it's -# probably a relative path) -# -# If there is a directory ./patch-scripts then use that -# -# Otherwise use "." -# - -if [ x$PATCHSCRIPTS != x ] -then - P=$PATCHSCRIPTS -elif [ -d ./patch-scripts ] -then - P=./patch-scripts -elif [ -d ./patches ] -then - P=. -else - echo "could not locate your pc/ and patches/ directories" - exit 1 -fi - -top_patch() -{ - tail -1 $DB -} - -die() -{ - echo error: $* - exit 1 -} - -is_numeric() -{ - if echo $1 | egrep '^[0-9]*$' > /dev/null - then - return 0 - fi - return 1 -} - -is_applied_last() -{ - name="$(stripit $1)" - top_patch >$DB.1 - if grep "^$name$" "$DB.1" > /dev/null 2>&1 - then - rm $DB.1 - return 0 - else - rm $DB.1 - return 1 - fi -} - -is_applied() -{ - name=$(stripit "$1") - if grep "^$name$" "$DB" > /dev/null 2>&1 - then - return 0 - else - return 1 - fi -} - -can_apply() -{ - if patch -p1 --dry-run -i "$1" -f - then - return 0 - else - return 1 - fi -} - -can_remove() -{ - if patch -R -p1 --dry-run -i $P/patches/"$1".patch -f - then - return 0 - else - return 1 - fi -} - -remove_from_db() -{ - tmpfile=$(mktemp /tmp/p_XXXXXX) - name="$1" - sed -e "/^$name$/d" < "$DB" > $tmpfile - mv $tmpfile "$DB" -} - -stripit() -{ - ret=$(basename $1) - ret=$(echo $ret | sed -e 's/\.patch$//') - ret=$(echo $ret | sed -e 's/\.pc$//') - ret=$(echo $ret | sed -e 's/\.txt$//') - echo $ret -} - -top_is_current() -{ - patch_name=$(top_patch) - if [ x$patch_name == x ] - then - return 1 - else - patch_file=$P/patches/"$patch_name".patch - files=$(cat $P/pc/$patch_name.pc) - for file in $files - do - if [ $file -nt $patch_file ] - then - echo $file newer than $patch_file - return 0 - fi - done - fi - return 1 -} - -need_top_current() -{ - if top_is_current - then - echo "Error: Top patch is not up-to-date" - exit 1 - fi -} - -warn_top_current() -{ - if top_is_current - then - echo "Warning: Top patch is not up-to-date" - fi -} - -file_in_patch() -{ - file=$1 - patch=$2 - - if [ -e $P/pc/$patch.pc ] - then - if grep "^"$file"$" $P/pc/$patch.pc > /dev/null - then - return 0 - fi - fi - return 1 -} - -# copy_file_to_bup filename patchname -copy_file_to_bup() -{ - file=$1 - patch=$2 - bup="$file"~"$patch" - - if [ -e $bup ] - then - echo "Cannot install file $file in patch $patch: backup $bup exists" - exit 1 - fi - - if [ -e $file ] - then - cp $file "$file"~"$patch" - else - echo "file $file appears to be newly added" - fi -} - -install_file_in_patch() -{ - file=$1 - patch=$2 - - copy_file_to_bup $file $patch - echo $file >> $P/pc/$patch.pc -# touch $P/txt/$patch.txt -} - -need_file_there() -{ - if [ ! -e $1 ] - then - echo "File $1 does not exist" - exit 1 - fi -} - -desc() -{ - state=0 - while read x - do - if [ x"$x" = xDESC ] - then - state=1 - elif [ x"$x" = xEDESC ] - then - state=0 - elif [ $state = 1 ] - then - echo " $x" - fi - done -} - -body() -{ - file=$1 - - did_stuff=0 - while read x - do - if [ x"$x" = xEDESC ] - then - cat - did_stuff=1 - fi - done < $file - - if [ $did_stuff = 0 ] - then - cat $file - fi -} diff --git a/lustre/kernel_patches/scripts/pcpatch b/lustre/kernel_patches/scripts/pcpatch deleted file mode 100755 index fa53385..0000000 --- a/lustre/kernel_patches/scripts/pcpatch +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "pcpatch: recreate the pc file from patches/{patchname}.patch" - exit 1 -} - -doit() -{ - echo $* 1>&2 - $* || { - echo oops - exit 1 - } -} - -if [ $# != 1 -o "$1" = "help" ] -then - usage -fi -PATCH=$1 -PATCH_NAME=$(stripit $PATCH) -PC=$P/pc/$PATCH_NAME.pc - -if [ ! -e $P/patches/$PATCH_NAME.patch ] -then - echo "$P/patches/$PATCH_NAME.patch does not exist" - exit 1 -fi - -if is_applied "$PATCH" -then - echo $PATCH is applied! - exit 1 -fi - -touched-by-patch $P/patches/$PATCH_NAME.patch > $PC -echo Recreated $PC diff --git a/lustre/kernel_patches/scripts/poppatch b/lustre/kernel_patches/scripts/poppatch deleted file mode 100755 index 792cb9b..0000000 --- a/lustre/kernel_patches/scripts/poppatch +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: poppatch [npatches]" - exit 1 -} - -doit() -{ - echo $* 1>&2 - $* || { - echo oops - exit 1 - } -} - -if [ $# -gt 1 ] -then - usage -fi - -NR=1 -STOP_AT="" -if [ $# -eq 1 ] -then - if is_numeric $1 - then - NR=$1 - else - NR=1000 - STOP_AT=$(stripit $1) - fi -fi - -pop_one() -{ - TOP_PATCH=$(top_patch) - if [ x$TOP_PATCH == x ] - then - echo "no patches applied" - exit 0 - else - popped_patch="$(top_patch)" - if ! rpatch $(top_patch) - then - echo still at $(top_patch) - exit 1 - fi - echo - fi -} - -for i in $(seq 1 $NR) -do - pop_one - if [ x$STOP_AT != "x" ] - then - if [ $STOP_AT == $(toppatch) ] - then - exit 0 - fi - fi -done diff --git a/lustre/kernel_patches/scripts/prep-patch b/lustre/kernel_patches/scripts/prep-patch deleted file mode 100755 index 1d60ea9..0000000 --- a/lustre/kernel_patches/scripts/prep-patch +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -if [ $# -ne 1 ] -then - echo "Usage prep-patch patchname" - exit 1 -fi - -PATCHNAME=$(stripit $1) - -xcb -s 2 < $P/patches/$PATCHNAME.patch -head -2 $P/txt/$PATCHNAME.txt | tail -1 | tr -d '\n' | xcb -s 1 diff --git a/lustre/kernel_patches/scripts/pstatus b/lustre/kernel_patches/scripts/pstatus deleted file mode 100755 index f735d8d..0000000 --- a/lustre/kernel_patches/scripts/pstatus +++ /dev/null @@ -1,156 +0,0 @@ -#!/bin/sh - -# print out patch status. Usage: pstatus [ patchfile ... ] -# -# Stephen Cameron -# - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -if [ ! -f ./series ] -then - echo "./series does not exist." 1>&2 - exit 1 -fi - -if [ ! -d ./patches ] -then - echo "Directory ./patches does not exist." 1>&2 - exit 1 -fi - - -PATCHLIST="$*" -if [ "$PATCHLIST" = "" ] -then - series_optimize=yes - PATCHLIST=`cat series | sed -e 's/[.]patch[ ]*$//'` - SORTSERIES=`mktemp /tmp/ser.XXXXXX` || exit 1 - SORTPATCHES=`mktemp /tmp/pat.XXXXXX` || exit 1 - sed -e 's/^[ ]//' -e 's/[.]patch[ ]*$//' < series | \ - sort > $SORTSERIES - exists="`echo $P/patches/*.patch 2>/dev/null`" - if [ "$exists" != "$P/patches/*.patch" ] - then - ls -1 $P/patches/*.patch | sed -e 's/^.*\/patches\///' \ - -e 's/[.]patch[ ]*$//' | sort > $SORTPATCHES - PATCHLIST="$PATCHLIST"" `comm -1 -3 $SORTSERIES $SORTPATCHES`" - fi - rm -f $SORTPATCHES $SORTSERIES -else - series_optimize=no -fi - -NSERIES=`wc -l series | awk '{ print $1; }'` -series=1 -for PATCH_NAME in $PATCHLIST -do - PATCH_NAME=$(stripit $PATCH_NAME) - # see if this patch even exists - if [ ! -f $P/patches/"$PATCH_NAME".patch ] - then - echo "$PATCH_NAME does not exist." - continue - fi - # see if this patch is applied - applied="-" - if [ -f applied-patches ] - then - grep '^'"$PATCH_NAME"'$' applied-patches > /dev/null - if [ "$?" = "0" ] - then - applied="a" - fi - fi - - # figure the status of this patch, that is, - # if it needs changelog, pcpatch, refpatch - - stat="" - if [ ! -f $P/txt/"$PATCH_NAME".txt ] - then - stat="changelog " - fi - if [ ! -f $P/pc/"$PATCH_NAME".pc ] - then - stat="$stat""pcpatch " - elif [ "$applied" != '-' ] - then - rpatch=n - - # for each file this patch touches - for y in `cat $P/pc/"$PATCH_NAME".pc` - do - # is the patch adding the file? - if [ ! -e "$y"'~'"$PATCH_NAME" -a -f "$y" ] - then - # file is newer than the patch? - if [ "$y" -nt $P/patches/"$PATCH_NAME".patch ] - then - rpatch=y - stat="$stat""refpatch " - break - fi - else - # modified file is newer than the patch? - if [ "$y"'~'"$PATCH_NAME" -nt \ - $P/patches/"$PATCH_NAME".patch ] - then - rpatch=y - stat="$stat""refpatch " - break - fi - if [ "`toppatch`" = "$PATCH_NAME" -a \ - "$y" -nt $P/patches/"$PATCH_NAME".patch ] - then - # toppatch, so check if the file - # is newer than the patch? - rpatch=y - stat="$stat""refpatch " - break - fi - fi - done - fi - # check if they changed the changelog recently - if [ "$rpatch" = "n" -a -f $P/txt/"$PATCH_NAME".txt \ - -a $P/txt/"$PATCH_NAME".txt -nt \ - $P/patches/"$PATCH_NAME".patch ] - then - rpatch=y - stat="$stat""refpatch " - fi - if [ "$stat" != "" ] - then - stat="Needs ""$stat" - fi - - if [ "$series_optimize" != "yes" ] - then - # have to find the series number the hard way. - series=`grep -n '^'"$PATCH_NAME"'\.patch$' series |\ - awk -F: '{ printf "%d", $1}' ` - if [ "$series" = "" ] - then - series="?" - fi - fi - - echo "$series":"$applied":"$PATCH_NAME $stat" - - if [ "$series_optimize" = "yes" ] - then - if [ "$series" != "?" ] - then - series=`expr $series + 1` - if [ $series -gt $NSERIES ] - then - series="?" - fi - fi - fi -done diff --git a/lustre/kernel_patches/scripts/ptkdiff b/lustre/kernel_patches/scripts/ptkdiff deleted file mode 100755 index 97c9982..0000000 --- a/lustre/kernel_patches/scripts/ptkdiff +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh - -# -# Bring up a patched file in tkdiff. We show the diffs -# in the topmost patch, unless it was specified -# - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: ptkdiff filename ..." - echo " ptkdiff -" - exit 1 -} - -PATCH_NAME=$(top_patch) - -doit() -{ - filename=$1 - unpatched_file=$filename"~"$PATCH_NAME - need_file_there $filename - if [ -e $unpatched_file ] - then - tkdiff $unpatched_file $filename - else - echo ptkdiff: $filename appears to not be in $PATCH_NAME - fi -} - -if [ x"$1" = "x-" ] -then - FILENAME=$(cat $P/pc/$PATCH_NAME.pc) -else - FILENAME="$*" -fi - -for i in $FILENAME -do - doit $i & -done diff --git a/lustre/kernel_patches/scripts/pushpatch b/lustre/kernel_patches/scripts/pushpatch deleted file mode 100755 index 018716d..0000000 --- a/lustre/kernel_patches/scripts/pushpatch +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/sh - -# -# Add next patch in series -# - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: pushpatch [npatches]" - exit 1 -} - -opt_force=0 - -for i in $* -do - case "$i" in - -f) - opt_force=1;; - *) - if [ -n "$NR" -o -n "$STOP_AT" ] - then - usage - fi - if is_numeric $i - then - NR=$i - else - NR=1000 - STOP_AT=$(stripit $i) - fi;; - esac -done - -[ $opt_force = 1 ] && force="-f" - -SERIES=series - -if [ ! -e $SERIES ] -then - echo 'File "series" not found' - exit 1 -fi - -push_one() -{ - top=$(toppatch) - if [ x"$top" == x ] - then - todo=$(head -1 $SERIES) - else - last_in_series=$(stripit $(tail -1 $SERIES)) - if [ $last_in_series == $top ] - then - echo "Series fully applied. Ends at $top" - exit 0 - fi - todo=$(grep -C1 "^$top\.patch" $SERIES | tail -1) - if [ x$todo = x ] - then - todo=$(head -1 $SERIES) - fi - fi - - apatch $force $todo -} - -for i in $(seq 1 $NR) -do - push_one - if [ x$STOP_AT != "x" ] - then - if [ $STOP_AT == $(toppatch) ] - then - exit 0 - fi - fi -done diff --git a/lustre/kernel_patches/scripts/refpatch b/lustre/kernel_patches/scripts/refpatch deleted file mode 100755 index 88f3caf..0000000 --- a/lustre/kernel_patches/scripts/refpatch +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: refpatch" - exit 1 -} - -doit() -{ - echo $* 1>&2 - $* || { - echo oops - exit 1 - } -} - -if [ $# != 0 ] -then - usage -fi - -TOP_PATCH=$(top_patch) -mpatch $* $(top_patch) -echo "Refreshed $TOP_PATCH" diff --git a/lustre/kernel_patches/scripts/removed-by-patch b/lustre/kernel_patches/scripts/removed-by-patch deleted file mode 100755 index ff12970..0000000 --- a/lustre/kernel_patches/scripts/removed-by-patch +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# Extract names of new files from a patch, print them out - -PATCHFILE=$1 -case "$PATCHFILE" in -*.gz) CMD="gzip -d < $PATCHFILE";; -*) CMD="cat $PATCHFILE";; -esac - -TMP=$(mktemp /tmp/rbp-XXXXXX) - -eval $CMD | egrep '^\+\+\+.*1970|\+\+\+.*1969' > $TMP -sed -e 's@[^/]*/\([^ ]*\).*@\1@' < $TMP | sed -e 's@^linux/@@' | sort -rm -f $TMP diff --git a/lustre/kernel_patches/scripts/rename-patch b/lustre/kernel_patches/scripts/rename-patch deleted file mode 100755 index 8334f1e..0000000 --- a/lustre/kernel_patches/scripts/rename-patch +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} -OLD=$(stripit $1) -NEW=$(stripit $2) - -mv $P/pc/$OLD.pc $P/pc/$NEW.pc -mv $P/patches/$OLD.patch $P/patches/$NEW.patch -mv $P/txt/$OLD.txt $P/txt/$NEW.txt - -cvs remove $P/pc/$OLD.pc -cvs remove $P/patches/$OLD.patch -cvs remove $P/txt/$OLD.txt - -cvs add $P/pc/$NEW.pc -cvs add $P/patches/$NEW.patch -cvs add $P/txt/$NEW.txt diff --git a/lustre/kernel_patches/scripts/rolled-up-patch b/lustre/kernel_patches/scripts/rolled-up-patch deleted file mode 100755 index 52676dc..0000000 --- a/lustre/kernel_patches/scripts/rolled-up-patch +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: rolled-up-patch" - exit 1 -} - -if [ $# != 0 ] -then - usage -fi - -RUP=$(mktemp /tmp/rup-XXXXXX) -rm -f $RUP - -for i in $(cat applied-patches) -do - patch_name=$(stripit $i) - cat $P/pc/$patch_name.pc -done | sort | uniq > $RUP - -kdiff $(cat $RUP) -rm -f $RUP diff --git a/lustre/kernel_patches/scripts/rpatch b/lustre/kernel_patches/scripts/rpatch deleted file mode 100755 index 42e1533..0000000 --- a/lustre/kernel_patches/scripts/rpatch +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -do_remove() -{ - if patch -R -p1 -s -i $P/patches/"$1".patch - then - true - else - echo SOMETHING WENT WRONG - exit 1 - fi -} - -kill_old_ones() -{ - FILES=$(cat $P/pc/$1.pc) - for file in $FILES - do - rm -f "$file"~"$1" - done -} - -usage() -{ - echo "Usage: rpatch patchname" - exit 1 -} - -if [ $# == 0 ] -then - usage -fi - -PATCH_NAME=$(stripit $1) - -warn_top_current - -if is_applied "$PATCH_NAME" -then - if can_remove "$PATCH_NAME" - then - do_remove "$PATCH_NAME" - kill_old_ones "$PATCH_NAME" - remove_from_db "$PATCH_NAME" - else - echo "$PATCH_NAME" does not remove cleanly - exit 1 - fi -else - echo "$PATCH_NAME" is not applied - exit 1 -fi - -top=$(top_patch) -if [ x"$top" == x ] -then - msg="no patches applied" -else - msg="now at $top" -fi - -echo Removed $PATCH_NAME, $msg - diff --git a/lustre/kernel_patches/scripts/split-patch b/lustre/kernel_patches/scripts/split-patch deleted file mode 100755 index 08ce431..0000000 --- a/lustre/kernel_patches/scripts/split-patch +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/perl -w -$out = ""; -while (<>) { - next if (/^Only/); - next if (/^Binary/); - if (/^diff/ || /^Index/) { - if ($out) { - close OUT; - } - (@out) = split(' ', $_); - shift(@out) if (/^diff/); - $out = pop(@out); - $out =~ s:/*usr/:/:; - $out =~ s:/*src/:/:; - $out =~ s:^/*linux[^/]*::; - $out =~ s:\(w\)::; - next if ($out eq ""); - $out = "/var/tmp/patches/$out"; - $dir = $out; - $dir =~ s:/[^/]*$::; - print STDERR "$out\n"; - system("mkdir -p $dir"); - open(OUT, ">$out") || die("cannot open $out"); - } - if ($out) { - print OUT $_; - } -} - diff --git a/lustre/kernel_patches/scripts/tag-series b/lustre/kernel_patches/scripts/tag-series deleted file mode 100755 index 17f3dfe..0000000 --- a/lustre/kernel_patches/scripts/tag-series +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -# tag-series tagname series-file-name -# -# Does a `cvs tag tagname' of all the .pc, .txt and .patch files mentioned -# in series-file-name. Also tags series-file-name. -# - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -# tag_one tag patchname -# -tag_one() -{ - PN=$(stripit $2) - if [ -r $P/txt/$PN.txt ] - then - cvs tag $1 $P/pc/$PN.pc $P/patches/$PN.patch $P/txt/$PN.txt - else - cvs tag $1 $P/pc/$PN.pc $P/patches/$PN.patch - fi -} - -if [ $# -ne 2 ] -then - echo Usage: tag-series tagname series-file-name - exit 1 -fi - -TAG=$1 -SERIES=$2 - -for p in $(cat $SERIES) -do - tag_one $TAG $p -done -cvs tag $TAG $SERIES diff --git a/lustre/kernel_patches/scripts/toppatch b/lustre/kernel_patches/scripts/toppatch deleted file mode 100755 index 6df239d..0000000 --- a/lustre/kernel_patches/scripts/toppatch +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -. patchfns >/dev/null || . /usr/lib/patch-scripts/patchfns >/dev/null || { \ - echo "Impossible to find my library 'patchfns'." - echo "Check your install, or go to the right directory" - exit 1 -} - -usage() -{ - echo "Usage: toppatch" - exit 1 -} - -if [ $# != 0 ] -then - usage -fi - -if [ -e $DB ] -then - TOP_PATCH=$(top_patch) - if [ x$TOP_PATCH != x ] - then - echo $TOP_PATCH - fi -fi diff --git a/lustre/kernel_patches/scripts/touched-by-patch b/lustre/kernel_patches/scripts/touched-by-patch deleted file mode 100755 index df5b387..0000000 --- a/lustre/kernel_patches/scripts/touched-by-patch +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# Extract names of new files from a patch, print them out - -PATCHFILE=$1 -case "$PATCHFILE" in -*.gz) CMD="gzip -d < $PATCHFILE";; -*) CMD="cat $PATCHFILE";; -esac - -TMP=$(mktemp /tmp/tbp-XXXXXX) || exit 1 -TMP2=$(mktemp /tmp/tbp2-XXXXXX) || exit 1 - -eval $CMD | egrep '^\+\+\+ |^\-\-\- ' > $TMP - -cat $TMP | sed -e 's@[^/]*/\([^ ]*\).*@\1@' \ - | grep -v '^dev\/null$' \ - | sort \ - | uniq \ - > $TMP2 - -rm -f $TMP -grep < $TMP2 '^[+][+][+]' > /dev/null -if [ "$?" = "0" ] -then - echo "WARNING: $PATCHFILE appears to be -p0 form rather than -p1." 1>&2 - echo " Use "\'"p0-2-p1 . . < $PATCHFILE"\'" to fix" 1>&2 - awk '{ print $2 }' < $TMP2 -else - cat $TMP2 -fi | grep -v '~' - -rm -f $TMP2 diff --git a/lustre/kernel_patches/scripts/unitdiff.py b/lustre/kernel_patches/scripts/unitdiff.py deleted file mode 100755 index d19d5e7..0000000 --- a/lustre/kernel_patches/scripts/unitdiff.py +++ /dev/null @@ -1,223 +0,0 @@ -#!/usr/bin/python - -import sys -import re -import string - -#TODO -# clean up rest/file -# clean up +6 and like (assumptions). should be turned into 'find' -# make regession tests for all cases (Only in, etc) - -try: - filename = sys.argv[1] -except: - print 'requires a file name' - sys.exit(1) - -filefd = open(filename) -file = filefd.read() -filefd.close() - -rest = file -pat = "(^(?:diff .*\n)?--- .*\n\+\+\+ .*)?\n@@ -(\d+),?(\d+)? \+(\d+),?(\d+)? @@|^(Only in .*)" -startpat = re.compile(pat, re.M) - -pos = 0 -oldpos = 0 -filelen = len(rest) -oldrest = "" -while(1): - rexp = startpat.search(rest) - if not rexp: - break - - if rexp.group(6): - print rexp.group(6) - rest = rest[rexp.end(6)+1:] - continue - - header = rexp.group(1) - orgfile_start = string.atoi(rexp.group(2)) - if rexp.group(3): - orgfile_len = string.atoi(rexp.group(3)) - else: - orgfile_len = -1 - newfile_start = string.atoi(rexp.group(4)) - if rexp.group(5): - newfile_len = string.atoi(rexp.group(5)) - else: - newfile_len = -1 - rest = rest[rexp.start(2):] - rest = rest[string.find(rest, "\n")+1:] - - rexp2 = startpat.search(rest) - if rexp2: - if rexp2.start(6) != -1: - oldrest = rest[rexp2.start(6)-1:] - rest = rest[:rexp2.start(6)] - elif rexp2.start(1) == -1: - oldrest = rest[rexp2.start(2)-5:] - rest = rest[:rexp2.start(2)-4] - else: - oldrest = rest[rexp2.start(1)-1:] - rest = rest[:rexp2.start(1)] - else: - oldrest = rest - -# pos = filelen - len(oldrest) -# if pos - oldpos > 100: -# sys.stderr.write(`pos`+'/'+`filelen`+'\n') -# oldpos = pos - - first = 1 - oldminuses = 0 - oldplusses = 0 - oldoffset = 0 - while(1): - #erstat early line stuff med lookbehind paa {1,2}-dims - #nedenfor RAA - linepat = "^([^-+\n]*)\n?(((^[-+].*\n)|^(.*\n){1,2}(?=^[-+].*\n))+)(.*)\n?" - compat = re.compile(linepat, re.M) - rexp = compat.search(rest) - if not rexp: - break - - prematch = rexp.group(1) - match = rexp.group(2) - muddle = len(match) - -# print rest -# print 'prematch ', rexp.start(1), rexp.end(1), prematch -# print 'match ---------' -# print match -# print 'match --------' - - # dump unwanted early lines... - if match[0] != "+" and match[0] != "-": - while(1): - next = string.find(match, '\n') - if next == -1: - break - if match[next+1] == "+" or match[next+1] == "-": - prematch = match[:next] - match = match[next+1:] - break - match = match[next+1:] - - -# print 'prematch ', rexp.start(1), rexp.end(1), len(prematch) -# print '('+prematch+')' -# if prematch == ' ': -# print 'space' - muddle = muddle - len(match) - - lines = string.count(match, "\n") - compat = re.compile("^-", re.M) - minuses = len(compat.findall(match)) - compat = re.compile("^\+", re.M) - plusses = len(compat.findall(match)) - orgsize = minuses + 2 + (lines - minuses - plusses) - newsize = plusses + 2 + (lines - minuses - plusses) - - noeol = "^(\\\ No newline at end of file)$" - compnoeol = re.compile(noeol, re.M) - if compnoeol.search(match) or compnoeol.search(rexp.group(6)): - orgsize = orgsize - 1 - newsize = newsize - 1 - - coherent = 0 - if lines - plusses == 0: - coherent = 1 - elif lines - minuses == 0: - coherent = 1 - - # RAA FIXME - if not len(prematch):#or len(prematch) == 1 and prematch == ' ': - orgsize = orgsize -1 - newsize = newsize -1 - if rexp.start(6) == rexp.end(6): - orgsize = orgsize -1 - newsize = newsize -1 - -# print "lines in match: ", lines -# print "number of minuses: ", minuses -# print "number of plusses: ", plusses - - matchpos = rexp.start(2) + muddle - offset = string.count(rest[:matchpos], "\n") - -# print 'offset/oldoffset: ', offset,oldoffset -# print 'oldplusses/oldminuses: ', oldplusses, oldminuses -# print 'orgfile_start/newfile_start: ', orgfile_start, newfile_start - - orgstart = orgfile_start + offset + oldoffset - oldplusses - newstart = newfile_start + offset - oldminuses + oldoffset - - # RAA: Bwadr. Fix antagelse om prematch paa en anden - # maade - orgstartmod = 0 - newstartmod = 0 - if orgfile_start == 1 and not len(prematch): - orgstartmod = 1 - if newfile_start == 1 and not len(prematch): - newstartmod = 1 - if orgfile_start == 0 and orgfile_len == 0: - orgstartmod = 1 - # RAA Hack! - plusses = plusses + 1 - minuses = minuses +1 - if newfile_start == 0 and newfile_len == 0: - newstartmod = 1 - # RAA Hack! - plusses = plusses + 1 - minuses = minuses +1 - - if header and first: - print header - first = 0 - - # should the start(1) == 0 be orgstart == 1? RAA - if orgstart == 1 and newstart == 1 and plusses == 0 and coherent: - print "@@ -"+`orgstart`+","+`orgsize`+" +"+`newstart`+" @@" - print match[:string.rfind(match, "\n")] - print rexp.group(6) - elif rexp.start(6) == rexp.end(6) and plusses == 0 and coherent: - if orgstartmod: - orgstart = orgstart + 1 - if newstartmod: - newstart = newstart + 1 - print "@@ -"+`orgstart-1`+","+`orgsize`+" +"+`newstart-1`+" @@" - print prematch - print match[:string.rfind(match, "\n")] - elif orgstart == 1 and orgstart == 1 and minuses == 0 and coherent: - print "@@ -"+`orgstart`+" +"+`newstart`+","+`newsize`+" @@" - print match[:string.rfind(match, "\n")] - print rexp.group(6) - elif rexp.start(6) == rexp.end(6) and minuses == 0 and coherent: - if orgstartmod: - orgstart = orgstart + 1 - if newstartmod: - newstart = newstart + 1 - print "@@ -"+`orgstart-1`+" +"+`newstart-1`+","+`newsize`+" @@" - print prematch - print match[:string.rfind(match, "\n")] - else: - if orgstartmod: - orgstart = orgstart + 1 - if newstartmod: - newstart = newstart + 1 - print "@@ -"+`orgstart-1`+","+`orgsize`+" +"+`newstart-1`+","+`newsize`+" @@" - if len(prematch): - print prematch - print match[:string.rfind(match, "\n")] - if rexp.start(6) != rexp.end(6): - print rexp.group(6) - - rest = rest[rexp.end(6):] - oldminuses = minuses + oldminuses - oldplusses = plusses + oldplusses - oldoffset = oldoffset + offset + lines #include match()-lines - - - rest = oldrest diff --git a/lustre/kernel_patches/series/chaos b/lustre/kernel_patches/series/chaos deleted file mode 100644 index 913ae18..0000000 --- a/lustre/kernel_patches/series/chaos +++ /dev/null @@ -1,7 +0,0 @@ -dev_read_only.patch -exports.patch -kmem_cache_validate.patch -lustre_version.patch -vfs_intent-2.4.18-18.patch -invalidate_show.patch -iod-rmap-exports.patch diff --git a/lustre/kernel_patches/series/hp-pnnl b/lustre/kernel_patches/series/hp-pnnl deleted file mode 100644 index 6723ab6..0000000 --- a/lustre/kernel_patches/series/hp-pnnl +++ /dev/null @@ -1,7 +0,0 @@ -dev_read_only_hp.patch -exports_hp.patch -kmem_cache_validate_hp.patch -jbd-transno-cb.patch -lustre_version.patch -vfs_intent_hp.patch -invalidate_show.patch diff --git a/lustre/kernel_patches/series/rh-2.4.18-18 b/lustre/kernel_patches/series/rh-2.4.18-18 deleted file mode 100644 index 51a833f..0000000 --- a/lustre/kernel_patches/series/rh-2.4.18-18 +++ /dev/null @@ -1,10 +0,0 @@ -dev_read_only.patch -exports.patch -kmem_cache_validate.patch -lustre_version.patch -uml_check_get_page.patch -uml_no_panic.patch -vfs_intent-2.4.18-18.patch -uml_compile_fixes.patch -invalidate_show.patch -iod-rmap-exports.patch diff --git a/lustre/kernel_patches/series/rh-8.0 b/lustre/kernel_patches/series/rh-8.0 deleted file mode 100644 index 2ba39f5..0000000 --- a/lustre/kernel_patches/series/rh-8.0 +++ /dev/null @@ -1,9 +0,0 @@ -dev_read_only.patch -exports.patch -kmem_cache_validate.patch -lustre_version.patch -uml_check_get_page.patch -uml_no_panic.patch -vfs_intent.patch -uml_compile_fixes.patch -invalidate_show.patch diff --git a/lustre/kernel_patches/series/vanilla-2.4.18 b/lustre/kernel_patches/series/vanilla-2.4.18 deleted file mode 100644 index 5d2ab68..0000000 --- a/lustre/kernel_patches/series/vanilla-2.4.18 +++ /dev/null @@ -1,2 +0,0 @@ -vanilla-2.4.18 -invalidate_show.patch diff --git a/lustre/kernel_patches/series/vanilla-2.4.19 b/lustre/kernel_patches/series/vanilla-2.4.19 deleted file mode 100644 index 37cb65e..0000000 --- a/lustre/kernel_patches/series/vanilla-2.4.19 +++ /dev/null @@ -1,3 +0,0 @@ -vanilla-2.4.19.patch -jbd-transno-cb.patch -invalidate_show.patch diff --git a/lustre/kernel_patches/series/vanilla-2.5 b/lustre/kernel_patches/series/vanilla-2.5 deleted file mode 100644 index 3269420..0000000 --- a/lustre/kernel_patches/series/vanilla-2.5 +++ /dev/null @@ -1,2 +0,0 @@ -lustre_version.patch -lustre-2.5.patch diff --git a/lustre/kernel_patches/txt/dev_read_only.txt b/lustre/kernel_patches/txt/dev_read_only.txt deleted file mode 100644 index 010cdb7..0000000 --- a/lustre/kernel_patches/txt/dev_read_only.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -(undescribed patch) -EDESC diff --git a/lustre/kernel_patches/txt/exports.txt b/lustre/kernel_patches/txt/exports.txt deleted file mode 100644 index 00b991e..0000000 --- a/lustre/kernel_patches/txt/exports.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -Required kernel function exports for Lustre. -EDESC diff --git a/lustre/kernel_patches/txt/exports_hp.txt b/lustre/kernel_patches/txt/exports_hp.txt deleted file mode 100644 index 00b991e..0000000 --- a/lustre/kernel_patches/txt/exports_hp.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -Required kernel function exports for Lustre. -EDESC diff --git a/lustre/kernel_patches/txt/invalidate_show.txt b/lustre/kernel_patches/txt/invalidate_show.txt deleted file mode 100644 index 88f093a..0000000 --- a/lustre/kernel_patches/txt/invalidate_show.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -Prints which inodes are busy at filesystem unmount time. -EDESC diff --git a/lustre/kernel_patches/txt/kmem_cache_validate.txt b/lustre/kernel_patches/txt/kmem_cache_validate.txt deleted file mode 100644 index 010cdb7..0000000 --- a/lustre/kernel_patches/txt/kmem_cache_validate.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -(undescribed patch) -EDESC diff --git a/lustre/kernel_patches/txt/lustre_version.txt b/lustre/kernel_patches/txt/lustre_version.txt deleted file mode 100644 index 010cdb7..0000000 --- a/lustre/kernel_patches/txt/lustre_version.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -(undescribed patch) -EDESC diff --git a/lustre/kernel_patches/txt/uml_check_get_page.txt b/lustre/kernel_patches/txt/uml_check_get_page.txt deleted file mode 100644 index 010cdb7..0000000 --- a/lustre/kernel_patches/txt/uml_check_get_page.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -(undescribed patch) -EDESC diff --git a/lustre/kernel_patches/txt/uml_compile_fixes.txt b/lustre/kernel_patches/txt/uml_compile_fixes.txt deleted file mode 100644 index 010cdb7..0000000 --- a/lustre/kernel_patches/txt/uml_compile_fixes.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -(undescribed patch) -EDESC diff --git a/lustre/kernel_patches/txt/uml_no_panic.txt b/lustre/kernel_patches/txt/uml_no_panic.txt deleted file mode 100644 index 010cdb7..0000000 --- a/lustre/kernel_patches/txt/uml_no_panic.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -(undescribed patch) -EDESC diff --git a/lustre/kernel_patches/txt/vfs_intent.txt b/lustre/kernel_patches/txt/vfs_intent.txt deleted file mode 100644 index 010cdb7..0000000 --- a/lustre/kernel_patches/txt/vfs_intent.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -(undescribed patch) -EDESC diff --git a/lustre/kernel_patches/which_patch b/lustre/kernel_patches/which_patch deleted file mode 100644 index b7af3d9..0000000 --- a/lustre/kernel_patches/which_patch +++ /dev/null @@ -1,10 +0,0 @@ -series/chaos - chaos-39 -series/rh-2.4.18-18 - redhat 2.4.18-18 -series/hp-pnnl ** Note: functionally equivalent to 2.4.19 - linux-2.4.18-hp2_pnnl2 -series/vanilla-2.4.19 ** Not officially supported - linux-2.4.19 -series/lin-2.5.44 - uml-2.5.44 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 d0c4199..0000000 --- a/lustre/ldlm/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= - -LDLMSOURCES= l_lock.c ldlm_lock.c ldlm_resource.c \ -ldlm_extent.c ldlm_request.c ldlm_lockd.c - -if LIBLUSTRE -lib_LIBRARIES = libldlm.a -libldlm_a_SOURCES = $(LDLMSOURCES) -else -MODULE = ldlm -modulefs_DATA = ldlm.o -EXTRA_PROGRAMS = ldlm - -ldlm_SOURCES = $(LDLMSOURCES) -endif - -include $(top_srcdir)/Rules - - diff --git a/lustre/ldlm/l_lock.c b/lustre/ldlm/l_lock.c deleted file mode 100644 index c439eed..0000000 --- a/lustre/ldlm/l_lock.c +++ /dev/null @@ -1,116 +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 DEBUG_SUBSYSTEM S_LDLM -#ifdef __KERNEL__ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#else -#include -#endif - -#include -#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); - - /* This is safe to increment outside the spinlock because we - * can only have 1 CPU running on the current task - * (i.e. l_owner == current), regardless of the number of CPUs. - */ - 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 9b10854..0000000 --- a/lustre/ldlm/ldlm_extent.c +++ /dev/null @@ -1,114 +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 -#ifndef __KERNEL__ -# include -#endif - -#include -#include -#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_namespace *ns, struct ldlm_lock **lockp, - void *req_cookie, ldlm_mode_t mode, int flags, - void *data) -{ - struct ldlm_lock *lock = *lockp; - 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(&ns->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(&ns->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 81cc428..0000000 --- a/lustre/ldlm/ldlm_lock.c +++ /dev/null @@ -1,1169 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * 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 - -#ifdef __KERNEL__ -#include -#include -#include -#include -#else -#include -#include -#endif - -#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", -}; - -#ifdef __KERNEL__ -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_READDIR: - return "readdir"; - case IT_GETATTR: - return "getattr"; - case IT_LOOKUP: - return "lookup"; - case IT_UNLINK: - return "unlink"; - default: - CERROR("Unknown intent %d\n", it); - return "UNKNOWN"; - } -} -#endif - -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); - -static 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_namespace *ns, 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(ns, lock, req_cookie, mode, - flags, data); - } - - return ELDLM_OK; -} - -static 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) -{ - atomic_inc(&lock->l_refc); - return lock; -} - -void ldlm_lock_put(struct ldlm_lock *lock) -{ - struct ldlm_namespace *ns = lock->l_resource->lr_namespace; - ENTRY; - - if (atomic_dec_and_test(&lock->l_refc)) { - l_lock(&ns->ns_lock); - LDLM_DEBUG(lock, "final lock_put on destroyed lock, freeing"); - LASSERT(lock->l_destroyed); - LASSERT(list_empty(&lock->l_res_link)); - - spin_lock(&ns->ns_counter_lock); - ns->ns_locks--; - spin_unlock(&ns->ns_counter_lock); - - ldlm_resource_putref(lock->l_resource); - lock->l_resource = NULL; - - if (lock->l_parent) - LDLM_LOCK_PUT(lock->l_parent); - - PORTAL_SLAB_FREE(lock, ldlm_lock_slab, sizeof(*lock)); - 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; -} - -/* This used to have a 'strict' flact, which recovery would use to mark an - * in-use lock as needing-to-die. Lest I am ever tempted to put it back, I - * shall explain why it's gone: with the new hash table scheme, once you call - * ldlm_lock_destroy, you can never drop your final references on this lock. - * Because it's not in the hash table anymore. -phil */ -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_ERROR(lock, "still has children (%p)!", - lock->l_children.next); - ldlm_lock_dump(D_ERROR, lock); - LBUG(); - } - if (lock->l_readers || lock->l_writers) { - LDLM_ERROR(lock, "lock still has references"); - ldlm_lock_dump(D_ERROR, lock); - LBUG(); - } - - if (!list_empty(&lock->l_res_link)) { - ldlm_lock_dump(D_ERROR, 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_init(&lock->l_export_chain); - ldlm_lock_remove_from_lru(lock); - class_handle_unhash(&lock->l_handle); - -#if 0 - /* 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 */ - lock->l_export = NULL; - if (lock->l_export && lock->l_completion_ast) - lock->l_completion_ast(lock, 0); -#endif - - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - LDLM_LOCK_PUT(lock); - EXIT; -} - -/* this is called by portals_handle2object with the handle lock taken */ -static void lock_handle_addref(void *lock) -{ - LDLM_LOCK_GET((struct ldlm_lock *)lock); -} - -/* - * usage: pass in a resource on which you have done ldlm_resource_get - * pass in a parent lock on which you have done a ldlm_lock_get - * after return, ldlm_*_put the resource and 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(); - - PORTAL_SLAB_ALLOC(lock, ldlm_lock_slab, sizeof(*lock)); - if (lock == NULL) - RETURN(NULL); - - lock->l_resource = ldlm_resource_getref(resource); - - atomic_set(&lock->l_refc, 2); - 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 = LDLM_LOCK_GET(parent); - list_add(&lock->l_childof, &parent->l_children); - l_unlock(&parent->l_resource->lr_namespace->ns_lock); - } - - INIT_LIST_HEAD(&lock->l_handle.h_link); - class_handle_hash(&lock->l_handle, lock_handle_addref); - - RETURN(lock); -} - -int ldlm_lock_change_resource(struct ldlm_namespace *ns, struct ldlm_lock *lock, - struct ldlm_res_id new_resid) -{ - struct ldlm_resource *oldres = lock->l_resource; - 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.name[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); - } - - /* ...and the flowers are still standing! */ - ldlm_resource_putref(oldres); - - l_unlock(&ns->ns_lock); - RETURN(0); -} - -/* - * HANDLES - */ - -void ldlm_lock2handle(struct ldlm_lock *lock, struct lustre_handle *lockh) -{ - POISON(&lockh->addr, 0x69, sizeof(lockh->addr)); - lockh->cookie = lock->l_handle.h_cookie; -} - -/* 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 flags) -{ - struct ldlm_lock *lock = NULL, *retval = NULL; - ENTRY; - - LASSERT(handle); - - lock = class_handle2object(handle->cookie); - if (lock == NULL) - RETURN(NULL); - - LASSERT(lock->l_resource != NULL); - LASSERT(lock->l_resource->lr_namespace != NULL); - - l_lock(&lock->l_resource->lr_namespace->ns_lock); - - /* It's unlikely but possible that someone marked the lock as - * destroyed after we did handle2object on it */ - if (lock->l_destroyed) { - CDEBUG(D_INFO, "lock already destroyed: lock %p\n", lock); - LDLM_LOCK_PUT(lock); - GOTO(out, retval); - } - - if (flags && (lock->l_flags & flags)) { - LDLM_LOCK_PUT(lock); - GOTO(out, retval); - } - - if (flags) - lock->l_flags |= flags; - - retval = lock; - EXIT; - out: - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - return retval; -} - -struct ldlm_lock *ldlm_handle2lock_ns(struct ldlm_namespace *ns, - struct lustre_handle *handle) -{ - struct ldlm_lock *retval = NULL; - - l_lock(&ns->ns_lock); - retval = __ldlm_handle2lock(handle, 0); - l_unlock(&ns->ns_lock); - - 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, - void *data, int datalen) -{ - 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); - } - - w->w_data = data; - w->w_datalen = datalen; - 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); - EXIT; - 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, - struct ldlm_res_id, int flags); - -void ldlm_lock_decref_internal(struct ldlm_lock *lock, __u32 mode) -{ - struct ldlm_namespace *ns; - ENTRY; - - LDLM_DEBUG(lock, "ldlm_lock_decref(%s)", ldlm_lockname[mode]); - ns = lock->l_resource->lr_namespace; - l_lock(&ns->ns_lock); - if (mode == LCK_NL || mode == LCK_CR || mode == LCK_PR) { - LASSERT(lock->l_readers > 0); - lock->l_readers--; - } else { - LASSERT(lock->l_writers > 0); - lock->l_writers--; - } - - if (lock->l_flags & LDLM_FL_LOCAL && - !lock->l_readers && !lock->l_writers) { - /* If this is a local lock on a server namespace and this was - * the last reference, cancel the lock. */ - CDEBUG(D_INFO, "forcing cancel of local lock\n"); - lock->l_flags |= LDLM_FL_CBPENDING; - } - - if (!lock->l_readers && !lock->l_writers && - (lock->l_flags & LDLM_FL_CBPENDING)) { - /* If we received a blocked AST and this was the last reference, - * run the callback. */ - if (!ns->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"); - - if (lock->l_blocking_ast == NULL) { - /* The lock wasn't even fully formed; just destroy it */ - ldlm_lock_destroy(lock); - } - l_unlock(&ns->ns_lock); - - /* FIXME: need a real 'desc' here */ - if (lock->l_blocking_ast != NULL) - lock->l_blocking_ast(lock, NULL, lock->l_data, - LDLM_CB_BLOCKING); - } else if (ns->ns_client && !lock->l_readers && !lock->l_writers) { - /* If this is a client-side namespace and this was the last - * reference, put it on the LRU. */ - 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(&ns->ns_lock); - ldlm_cancel_lru(ns); - } else { - l_unlock(&ns->ns_lock); - } - - LDLM_LOCK_PUT(lock); /* matches the ldlm_lock_get in addref */ - - EXIT; -} - -void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode) -{ - struct ldlm_lock *lock = __ldlm_handle2lock(lockh, 0); - LASSERT(lock != NULL); - ldlm_lock_decref_internal(lock, mode); - LDLM_LOCK_PUT(lock); -} - -/* This will drop a lock reference and mark it for destruction, but will not - * necessarily cancel the lock before returning. */ -void ldlm_lock_decref_and_cancel(struct lustre_handle *lockh, __u32 mode) -{ - struct ldlm_lock *lock = __ldlm_handle2lock(lockh, 0); - ENTRY; - - LASSERT(lock != NULL); - - LDLM_DEBUG(lock, "ldlm_lock_decref(%s)", ldlm_lockname[mode]); - l_lock(&lock->l_resource->lr_namespace->ns_lock); - lock->l_flags |= LDLM_FL_CBPENDING; - ldlm_lock_decref_internal(lock, mode); - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - LDLM_LOCK_PUT(lock); -} - -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, NULL, 0); - } - } - - 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_lock_enqueue - * - ldlm_reprocess_queue - * - ldlm_lock_convert - */ -void ldlm_grant_lock(struct ldlm_lock *lock, void *data, int datalen) -{ - 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 != NULL) - ldlm_add_ast_work_item(lock, NULL, data, datalen); - - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - EXIT; -} - -/* returns a referenced lock or NULL. See the flag descriptions below, in the - * comment above ldlm_lock_match */ -static struct ldlm_lock *search_queue(struct list_head *queue, ldlm_mode_t mode, - struct ldlm_extent *extent, - struct ldlm_lock *old_lock, int flags) -{ - 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) - break; - - 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; - - if ((flags & LDLM_FL_LOCAL_ONLY) && - !(lock->l_flags & LDLM_FL_LOCAL)) - 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. - * - * If 'flags' contains LDLM_FL_LOCAL_ONLY, then only match local locks on the - * server (ie, connh is NULL) - * If 'flags' contains LDLM_FL_BLOCK_GRANTED, then only locks on the granted - * list will be considered - * - * 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, int flags, - struct ldlm_res_id *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); - - lock = search_queue(&res->lr_granted, mode, cookie, old_lock, flags); - if (lock != NULL) - GOTO(out, rc = 1); - if (flags & LDLM_FL_BLOCK_GRANTED) - GOTO(out, rc = 0); - lock = search_queue(&res->lr_converting, mode, cookie, old_lock, flags); - if (lock != NULL) - GOTO(out, rc = 1); - lock = search_queue(&res->lr_waiting, mode, cookie, old_lock, flags); - if (lock != NULL) - 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, NULL); - } - 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, - struct ldlm_res_id res_id, __u32 type, - ldlm_mode_t mode, void *data, void *cp_data) -{ - struct ldlm_resource *res, *parent_res = NULL; - struct ldlm_lock *lock, *parent_lock = NULL; - ENTRY; - - 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); - ldlm_resource_putref(res); - if (parent_lock != NULL) - LDLM_LOCK_PUT(parent_lock); - - if (lock == NULL) - RETURN(NULL); - - lock->l_req_mode = mode; - lock->l_data = data; - lock->l_cp_data = cp_data; - - RETURN(lock); -} - -ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *ns, - struct ldlm_lock **lockp, - void *cookie, int cookie_len, - int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback blocking) -{ - struct ldlm_resource *res; - struct ldlm_lock *lock = *lockp; - 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(ns, lockp, 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_REPLACED) { - /* The lock that was returned has already been granted, - * and placed into lockp. Destroy the old one and our - * work here is done. */ - ldlm_lock_destroy(lock); - LDLM_LOCK_PUT(lock); - *flags |= LDLM_FL_LOCK_CHANGED; - RETURN(0); - } else if (rc == ELDLM_LOCK_ABORTED) { - ldlm_lock_destroy(lock); - RETURN(rc); - } - } - - l_lock(&ns->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 268): Detect obvious lies by checking compatibility in - * granted/converting queues. */ - ldlm_resource_unlink_lock(lock); - if (local) { - if (*flags & LDLM_FL_BLOCK_CONV) - ldlm_resource_add_lock(res, &res->lr_converting, lock); - else if (*flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED)) - ldlm_resource_add_lock(res, &res->lr_waiting, lock); - else - ldlm_grant_lock(lock, NULL, 0); - GOTO(out, ELDLM_OK); - } else if (*flags & LDLM_FL_REPLAY) { - if (*flags & LDLM_FL_BLOCK_CONV) { - ldlm_resource_add_lock(res, &res->lr_converting, lock); - GOTO(out, ELDLM_OK); - } else if (*flags & LDLM_FL_BLOCK_WAIT) { - ldlm_resource_add_lock(res, &res->lr_waiting, lock); - GOTO(out, ELDLM_OK); - } else if (*flags & LDLM_FL_BLOCK_GRANTED) { - ldlm_grant_lock(lock, NULL, 0); - GOTO(out, ELDLM_OK); - } - /* If no flags, fall through to normal enqueue path. */ - } - - /* 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, lock); - *flags |= LDLM_FL_BLOCK_CONV; - GOTO(out, ELDLM_OK); - } - if (!list_empty(&res->lr_waiting)) { - ldlm_resource_add_lock(res, &res->lr_waiting, lock); - *flags |= LDLM_FL_BLOCK_WAIT; - GOTO(out, ELDLM_OK); - } - if (!ldlm_lock_compat(lock, 0)) { - ldlm_resource_add_lock(res, &res->lr_waiting, lock); - *flags |= LDLM_FL_BLOCK_GRANTED; - GOTO(out, ELDLM_OK); - } - - if (lock->l_granted_cb != NULL && lock->l_data != NULL) { - /* We just -know- */ - struct ptlrpc_request *req = lock->l_data; - lock->l_granted_cb(lock, req->rq_repmsg, 0); - } - ldlm_grant_lock(lock, NULL, 0); - EXIT; - out: - /* 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; - l_unlock(&ns->ns_lock); - 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, NULL, 0); - } - - RETURN(0); -} - -int ldlm_run_ast_work(struct list_head *rpc_list) -{ - struct list_head *tmp, *pos; - int rc, retval = 0; - ENTRY; - - list_for_each_safe(tmp, pos, rpc_list) { - struct ldlm_ast_work *w = - list_entry(tmp, struct ldlm_ast_work, w_list); - - /* It's possible to receive a completion AST before we've set - * the l_completion_ast pointer: either because the AST arrived - * before the reply, or simply because there's a small race - * window between receiving the reply and finishing the local - * enqueue. (bug 842) - * - * This can't happen with the blocking_ast, however, because we - * will never call the local blocking_ast until we drop our - * reader/writer reference, which we won't do until we get the - * reply and finish enqueueing. */ - if (w->w_blocking) { - LASSERT(w->w_lock->l_blocking_ast != NULL); - rc = w->w_lock->l_blocking_ast - (w->w_lock, &w->w_desc, w->w_data, - LDLM_CB_BLOCKING); - } else if (w->w_lock->l_completion_ast != NULL) { - rc = w->w_lock->l_completion_ast(w->w_lock, w->w_flags, - w->w_data); - } else { - rc = 0; - } - if (rc == -ERESTART) - retval = rc; - else 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)); - } - RETURN(retval); -} - -static int reprocess_one_queue(struct ldlm_resource *res, void *closure) -{ - ldlm_reprocess_all(res); - return LDLM_ITER_CONTINUE; -} - -void ldlm_reprocess_all_ns(struct ldlm_namespace *ns) -{ - (void)ldlm_namespace_foreach_res(ns, reprocess_one_queue, NULL); -} - -void ldlm_reprocess_all(struct ldlm_resource *res) -{ - struct list_head rpc_list = LIST_HEAD_INIT(rpc_list); - int rc; - ENTRY; - - /* Local lock trees don't get reprocessed. */ - if (res->lr_namespace->ns_client) { - EXIT; - return; - } - - restart: - 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); - - rc = ldlm_run_ast_work(&rpc_list); - if (rc == -ERESTART) - goto restart; - 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, - 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; - - ldlm_del_waiting_lock(lock); - - res = lock->l_resource; - ns = res->lr_namespace; - - l_lock(&ns->ns_lock); - /* Please do not, no matter how tempting, remove this LBUG without - * talking to me first. -phik */ - if (lock->l_readers || lock->l_writers) { - LDLM_DEBUG(lock, "lock still has references"); - ldlm_lock_dump(D_OTHER, lock); - LBUG(); - } - - ldlm_cancel_callback(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, void *cp_data) -{ - struct ldlm_lock *lock = ldlm_handle2lock(lockh); - ENTRY; - - if (lock == NULL) - RETURN(-EINVAL); - - lock->l_data = data; - lock->l_cp_data = cp_data; - - LDLM_LOCK_PUT(lock); - - RETURN(0); -} - -/* This function is only called from one thread (per export); no locking around - * the list ops needed */ -void ldlm_cancel_locks_for_export(struct obd_export *exp) -{ - struct list_head *iter, *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; - - LBUG(); - - 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, lock); - } else { - /* This should never happen, because of the way the - * server handles conversions. */ - LBUG(); - - res->lr_tmp = &rpc_list; - ldlm_grant_lock(lock, NULL, 0); - 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, NULL); - } - } 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, 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(int level, struct ldlm_lock *lock) -{ - char ver[128]; - - if (!((portal_debug | D_ERROR) & level)) - return; - - if (RES_VERSION_SIZE != 4) - LBUG(); - - if (!lock) { - CDEBUG(level, " 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(level, " -- Lock dump: %p (%s) (rc: %d)\n", lock, ver, - atomic_read(&lock->l_refc)); - if (lock->l_export && lock->l_export->exp_connection) - CDEBUG(level, " Node: NID "LPX64" on %s (rhandle: "LPX64")\n", - lock->l_export->exp_connection->c_peer.peer_nid, - lock->l_export->exp_connection->c_peer.peer_ni->pni_name, - lock->l_remote_handle.cookie); - else - CDEBUG(level, " Node: local\n"); - CDEBUG(level, " Parent: %p\n", lock->l_parent); - CDEBUG(level, " Resource: %p ("LPD64")\n", lock->l_resource, - lock->l_resource->lr_name.name[0]); - CDEBUG(level, " Requested mode: %d, granted mode: %d\n", - (int)lock->l_req_mode, (int)lock->l_granted_mode); - CDEBUG(level, " Readers: %u ; Writers; %u\n", - lock->l_readers, lock->l_writers); - if (lock->l_resource->lr_type == LDLM_EXTENT) - CDEBUG(level, " Extent: "LPU64" -> "LPU64"\n", - lock->l_extent.start, lock->l_extent.end); -} - -void ldlm_lock_dump_handle(int level, struct lustre_handle *lockh) -{ - struct ldlm_lock *lock; - - lock = ldlm_handle2lock(lockh); - if (lock == NULL) - return; - - ldlm_lock_dump(D_OTHER, lock); - - LDLM_LOCK_PUT(lock); -} diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c deleted file mode 100644 index c1d3182..0000000 --- a/lustre/ldlm/ldlm_lockd.c +++ /dev/null @@ -1,901 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * 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 - -#ifdef __KERNEL__ -#include -#include -#include -#else -#include -#endif - -#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; -} - -/* XXX should this be per-ldlm? */ -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; - CERROR("lock timer expired, lock %p\n", l); - 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 inline void ldlm_failed_ast(struct ldlm_lock *lock) -{ - /* XXX diagnostic */ - recovd_conn_fail(lock->l_export->exp_connection); -} - -int ldlm_server_blocking_ast(struct ldlm_lock *lock, - struct ldlm_lock_desc *desc, - void *data, 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); - } - - LASSERT(lock); - - l_lock(&lock->l_resource->lr_namespace->ns_lock); - /* XXX This is necessary because, with the lock re-tasking, we actually - * _can_ get called in here twice. (bug 830) */ - if (!list_empty(&lock->l_pending_chain)) { - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - RETURN(0); - } - - if (lock->l_destroyed) { - /* What's the point? */ - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - 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 = lustre_msg_size(0, NULL); - - ldlm_add_waiting_lock(lock); - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - - req->rq_level = LUSTRE_CONN_RECOVD; - rc = ptlrpc_queue_wait(req); - if (rc == -ETIMEDOUT || rc == -EINTR) { - ldlm_del_waiting_lock(lock); - ldlm_failed_ast(lock); - } else if (rc) { - CERROR("client returned %d from blocking AST for lock %p\n", - req->rq_status, lock); - LDLM_DEBUG(lock, "client returned error %d from blocking AST", - req->rq_status); - ldlm_lock_cancel(lock); - /* Server-side AST functions are called from ldlm_reprocess_all, - * which needs to be told to please restart its reprocessing. */ - rc = -ERESTART; - } - - ptlrpc_req_finished(req); - - RETURN(rc); -} - -int ldlm_server_completion_ast(struct ldlm_lock *lock, int flags, void *data) -{ - 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 = lustre_msg_size(0, NULL); - - req->rq_level = LUSTRE_CONN_RECOVD; - rc = ptlrpc_queue_wait(req); - if (rc == -ETIMEDOUT || rc == -EINTR) { - ldlm_del_waiting_lock(lock); - ldlm_failed_ast(lock); - } else if (rc) { - CERROR("client returned %d from completion AST for lock %p\n", - req->rq_status, lock); - LDLM_DEBUG(lock, "client returned error %d from completion AST", - req->rq_status); - ldlm_lock_cancel(lock); - /* Server-side AST functions are called from ldlm_reprocess_all, - * which needs to be told to please restart its reprocessing. */ - rc = -ERESTART; - } - ptlrpc_req_finished(req); - - RETURN(rc); -} - -int ldlm_handle_enqueue(struct ptlrpc_request *req, - ldlm_completion_callback completion_callback, - ldlm_blocking_callback blocking_callback) -{ - 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); - } - } - - /* The lock's callback data might be set in the policy function */ - lock = ldlm_lock_create(obddev->obd_namespace, - &dlm_req->lock_handle2, - dlm_req->lock_desc.l_resource.lr_name, - 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"); - - LASSERT(req->rq_export); - lock->l_export = req->rq_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); - - err = ldlm_lock_enqueue(obddev->obd_namespace, &lock, cookie, cookielen, - &flags, completion_callback, blocking_callback); - if (err) - 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; - } - - EXIT; - out: - if (lock) - LDLM_DEBUG(lock, "server-side enqueue handler, sending reply" - "(err=%d)", err); - req->rq_status = err; - - /* The LOCK_CHANGED code in ldlm_lock_enqueue depends on this - * ldlm_reprocess_all. If this moves, revisit that code. -phil */ - 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) { - CERROR("received cancel for unknown lock cookie "LPX64"\n", - dlm_req->lock_handle1.cookie); - LDLM_DEBUG_NOLOCK("server-side cancel handler stale lock " - "(cookie "LPU64")", - dlm_req->lock_handle1.cookie); - 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); -} - -struct ldlm_lock *ldlm_handle2lock_ns(struct ldlm_namespace *ns, - struct lustre_handle *handle); - -static int ldlm_handle_bl_callback(struct ptlrpc_request *req, - struct ldlm_namespace *ns) -{ - 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_ns(ns, &dlm_req->lock_handle1); - if (!lock) { - CDEBUG(D_INFO, "blocking callback on lock "LPX64 - " - lock disappeared\n", dlm_req->lock_handle1.cookie); - RETURN(-EINVAL); - } - - LDLM_DEBUG(lock, "client blocking AST callback handler START"); - - l_lock(&ns->ns_lock); - lock->l_flags |= LDLM_FL_CBPENDING; - do_ast = (!lock->l_readers && !lock->l_writers); - l_unlock(&ns->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, 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 ldlm_namespace *ns) -{ - 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_ns(ns, &dlm_req->lock_handle1); - if (!lock) { - CERROR("completion callback on lock "LPX64" - lock " - "disappeared\n", dlm_req->lock_handle1.cookie); - RETURN(-EINVAL); - } - - LDLM_DEBUG(lock, "client completion callback handler START"); - - l_lock(&ns->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(lock->l_resource->lr_name)) != 0) { - ldlm_lock_change_resource(ns, 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, req, sizeof(*req)); - lock->l_resource->lr_tmp = NULL; - l_unlock(&ns->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) -{ - struct ldlm_namespace *ns; - int rc; - ENTRY; - - rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); - if (rc) { - CERROR("Invalid request: %d\n", rc); - RETURN(rc); - } - - if (req->rq_export == NULL) { - struct ldlm_request *dlm_req; - - 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); - dlm_req = lustre_msg_buf(req->rq_reqmsg, 0); - CERROR("--> lock addr: "LPX64", cookie: "LPX64"\n", - dlm_req->lock_handle1.addr,dlm_req->lock_handle1.cookie); - rc = -ENOTCONN; - goto out; - } - - LASSERT(req->rq_export != NULL); - LASSERT(req->rq_export->exp_obd != NULL); - ns = req->rq_export->exp_obd->obd_namespace; - LASSERT(ns != NULL); - - 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, ns); - break; - 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, ns); - break; - default: - CERROR("invalid opcode %d\n", req->rq_reqmsg->opc); - RETURN(-EINVAL); - } - out: - req->rq_status = rc; - rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - RETURN(rc); - ptlrpc_reply(req->rq_svc, req); - - 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) { - struct ldlm_request *dlm_req; - 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); - dlm_req = lustre_msg_buf(req->rq_reqmsg, 0); - ldlm_lock_dump_handle(D_ERROR, &dlm_req->lock_handle1); - 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(unsigned int cmd, struct lustre_handle *conn, int len, - void *karg, void *uarg) -{ - struct obd_device *obddev = class_conn2obd(conn); - struct ptlrpc_connection *connection; - struct obd_uuid uuid = { "ldlm" }; - 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 %d, nr %d, size %d)\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(&uuid); - if (!connection) - CERROR("No LDLM UUID found: assuming ldlm is local.\n"); - - switch (cmd) { - case IOC_LDLM_TEST: - //err = ldlm_test(obddev, conn); - err = 0; - CERROR("-- NO TESTS WERE RUN 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); - - rc = ldlm_proc_setup(obddev); - if (rc != 0) - RETURN(rc); - -#ifdef __KERNEL__ - ldlm->ldlm_cb_service = - ptlrpc_init_svc(LDLM_NEVENTS, LDLM_NBUFS, LDLM_BUFSIZE, - LDLM_MAXREQSIZE, LDLM_CB_REQUEST_PORTAL, - LDLM_CB_REPLY_PORTAL, - 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, - 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); - } - } - -#endif - 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: -#ifdef __KERNEL__ - 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); -#endif - out_proc: - ldlm_proc_cleanup(obddev); - - 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); - } - -#ifdef __KERNEL__ - 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); -#endif - ldlm_already_setup = 0; - RETURN(0); -} - -static int ldlm_connect(struct lustre_handle *conn, struct obd_device *src, - struct obd_uuid *cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - return class_connect(conn, src, cluuid); -} - -struct obd_ops ldlm_obd_ops = { - o_owner: THIS_MODULE, - o_iocontrol: ldlm_iocontrol, - o_setup: ldlm_setup, - o_cleanup: ldlm_cleanup, - o_connect: ldlm_connect, - o_disconnect: class_disconnect -}; - -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"); -} - -/* ldlm_lock.c */ -EXPORT_SYMBOL(ldlm_lock2desc); -EXPORT_SYMBOL(ldlm_register_intent); -EXPORT_SYMBOL(ldlm_unregister_intent); -EXPORT_SYMBOL(ldlm_lockname); -EXPORT_SYMBOL(ldlm_typename); -EXPORT_SYMBOL(ldlm_lock2handle); -EXPORT_SYMBOL(__ldlm_handle2lock); -EXPORT_SYMBOL(ldlm_lock_put); -EXPORT_SYMBOL(ldlm_lock_match); -EXPORT_SYMBOL(ldlm_lock_cancel); -EXPORT_SYMBOL(ldlm_lock_addref); -EXPORT_SYMBOL(ldlm_lock_decref); -EXPORT_SYMBOL(ldlm_lock_decref_and_cancel); -EXPORT_SYMBOL(ldlm_lock_change_resource); -EXPORT_SYMBOL(ldlm_lock_set_data); -EXPORT_SYMBOL(ldlm_it2str); -EXPORT_SYMBOL(ldlm_lock_dump); -EXPORT_SYMBOL(ldlm_lock_dump_handle); -EXPORT_SYMBOL(ldlm_cancel_locks_for_export); -EXPORT_SYMBOL(ldlm_reprocess_all_ns); - -/* ldlm_request.c */ -EXPORT_SYMBOL(ldlm_completion_ast); -EXPORT_SYMBOL(ldlm_expired_completion_wait); -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_replay_locks); -EXPORT_SYMBOL(ldlm_resource_foreach); -EXPORT_SYMBOL(ldlm_namespace_foreach); -EXPORT_SYMBOL(ldlm_namespace_foreach_res); - -/* ldlm_lockd.c */ -EXPORT_SYMBOL(ldlm_server_blocking_ast); -EXPORT_SYMBOL(ldlm_server_completion_ast); -EXPORT_SYMBOL(ldlm_handle_enqueue); -EXPORT_SYMBOL(ldlm_handle_cancel); -EXPORT_SYMBOL(ldlm_handle_convert); -EXPORT_SYMBOL(ldlm_del_waiting_lock); - -#if 0 -/* ldlm_test.c */ -EXPORT_SYMBOL(ldlm_test); -EXPORT_SYMBOL(ldlm_regression_start); -EXPORT_SYMBOL(ldlm_regression_stop); -#endif - -/* ldlm_resource.c */ -EXPORT_SYMBOL(ldlm_namespace_new); -EXPORT_SYMBOL(ldlm_namespace_cleanup); -EXPORT_SYMBOL(ldlm_namespace_free); -EXPORT_SYMBOL(ldlm_namespace_dump); - -/* l_lock.c */ -EXPORT_SYMBOL(l_lock); -EXPORT_SYMBOL(l_unlock); - -#ifdef __KERNEL__ -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); -#endif diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c deleted file mode 100644 index d64a402..0000000 --- a/lustre/ldlm/ldlm_request.c +++ /dev/null @@ -1,873 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define DEBUG_SUBSYSTEM S_LDLM -#ifndef __KERNEL__ -#include -#include -#endif - -#include -#include -#include - -static int interrupted_completion_wait(void *data) -{ - RETURN(1); -} - -int ldlm_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 { - LDLM_DEBUG(lock, "timed out waiting for completion"); - CERROR("lock %p timed out from %s\n", lock, - conn->c_remote_uuid.uuid); - ldlm_lock_dump(D_ERROR, lock); - class_signal_connection_failure(conn); - } - RETURN(0); -} - -int ldlm_completion_ast(struct ldlm_lock *lock, int flags, void *data) -{ - struct l_wait_info lwi = - LWI_TIMEOUT_INTR(obd_timeout * HZ, ldlm_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(D_OTHER, 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, - struct ldlm_res_id res_id, - __u32 type, - void *cookie, int cookielen, - ldlm_mode_t mode, - int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback blocking, - void *data, - void *cp_data, - 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, cp_data); - 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_flags |= LDLM_FL_LOCAL; - - err = ldlm_lock_enqueue(ns, &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, NULL); - - 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, - struct ldlm_res_id res_id, - __u32 type, - void *cookie, int cookielen, - ldlm_mode_t mode, - int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback blocking, - void *data, - void *cp_data, - 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) { - rc = ldlm_cli_enqueue_local(ns, parent_lock_handle, res_id, - type, cookie, cookielen, mode, - flags, completion, blocking, data, - cp_data, lockh); - RETURN(rc); - } - - /* 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, cp_data); - if (lock == NULL) - GOTO(out_nolock, rc = -ENOMEM); - /* ugh. I set this early (instead of waiting for _enqueue) - * because the completion AST might arrive early, and we need - * (in just this one case) to run the completion_cb even if it - * arrives before the reply. */ - lock->l_completion_ast = completion; - 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"); - /* Set a flag to prevent us from sending a CANCEL (bug 407) */ - l_lock(&ns->ns_lock); - lock->l_flags |= LDLM_FL_CANCELING; - l_unlock(&ns->ns_lock); - - ldlm_lock_decref_and_cancel(lockh, mode); - GOTO(out_req, 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.name[0] != - lock->l_resource->lr_name.name[0]) { - CDEBUG(D_INFO, "remote intent success, locking %ld " - "instead of %ld\n", - (long)reply->lock_resource_name.name[0], - (long)lock->l_resource->lr_name.name[0]); - - ldlm_lock_change_resource(ns, lock, - reply->lock_resource_name); - if (lock->l_resource == NULL) { - LBUG(); - GOTO(out_req, rc = -ENOMEM); - } - LDLM_DEBUG(lock, "client-side enqueue, new resource"); - } - } - - if (!is_replay) { - l_lock(&ns->ns_lock); - lock->l_completion_ast = NULL; - rc = ldlm_lock_enqueue(ns, &lock, cookie, cookielen, flags, - completion, blocking); - l_unlock(&ns->ns_lock); - if (lock->l_completion_ast) - lock->l_completion_ast(lock, *flags, NULL); - } - - LDLM_DEBUG(lock, "client-side enqueue END"); - EXIT; - out_req: - if (!req_passed_in) - ptlrpc_req_finished(req); - 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, - struct ldlm_res_id res_id, - __u32 type, - void *cookie, int cookielen, - ldlm_mode_t mode, - int *flags, - ldlm_completion_callback completion, - ldlm_blocking_callback blocking, - void *data, - void *cp_data, - struct lustre_handle *lockh) -{ - int rc; - ENTRY; - if (connh == NULL) { - /* Just to make sure that I understand things --phil */ - LASSERT(*flags & LDLM_FL_LOCAL_ONLY); - } - - LDLM_DEBUG_NOLOCK("resource "LPU64"/"LPU64, res_id.name[0], - res_id.name[1]); - rc = ldlm_lock_match(ns, *flags, &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, - cp_data, lockh); - if (rc != ELDLM_OK) - CERROR("ldlm_cli_enqueue: err: %d\n", rc); - RETURN(rc); - } - RETURN(0); -} - -int ldlm_cli_replay_enqueue(struct ldlm_lock *lock) -{ - struct lustre_handle lockh; - struct ldlm_res_id junk; - int flags = LDLM_FL_REPLAY; - ldlm_lock2handle(lock, &lockh); - return ldlm_cli_enqueue(lock->l_connh, NULL, NULL, NULL, junk, - 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, NULL); - 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, LDLM_FL_CANCELING); - if (lock == NULL) - RETURN(0); - - if (lock->l_connh) { - int local_only; - - 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); - local_only = (lock->l_flags & LDLM_FL_LOCAL_ONLY); - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - - if (local_only) { - CDEBUG(D_INFO, "not sending request (at caller's " - "instruction\n"); - goto local_cancel; - } - - 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 == ESTALE) { - CERROR("client/server out of sync\n"); - LBUG(); - } - if (rc != ELDLM_OK) - CERROR("Got rc %d from cancel RPC: canceling " - "anyway\n", rc); - local_cancel: - 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"); - } - - 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, - struct ldlm_res_id 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.name[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); - - /* 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; - - 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); - - 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 flags & LDLM_FL_LOCAL_ONLY, throw the locks away without trying - * to notify the server. - * If flags & LDLM_FL_NO_CALLBACK, don't run the cancel callback. */ -int ldlm_cli_cancel_unused(struct ldlm_namespace *ns, - struct ldlm_res_id *res_id, int flags) -{ - int i; - ENTRY; - - if (ns == NULL) - RETURN(ELDLM_OK); - - 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.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); -} - -static int ldlm_res_iter_helper(struct ldlm_resource *res, void *closure) -{ - return ldlm_resource_foreach(res, ldlm_iter_helper, closure); -} - -int ldlm_namespace_foreach(struct ldlm_namespace *ns, ldlm_iterator_t iter, - void *closure) -{ - struct iter_helper_data helper = { iter: iter, closure: closure }; - return ldlm_namespace_foreach_res(ns, ldlm_res_iter_helper, &helper); -} - -int ldlm_namespace_foreach_res(struct ldlm_namespace *ns, - ldlm_res_iterator_t iter, void *closure) -{ - int i, rc = LDLM_ITER_CONTINUE; - - 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 = iter(res, closure); - 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) -{ - struct ptlrpc_request *req; - struct ldlm_request *body; - struct ldlm_reply *reply; - int rc, size; - int flags; - - /* - * If granted mode matches the requested mode, this lock is granted. - * - * If they differ, but we have a granted mode, then we were granted - * one mode and now want another: ergo, converting. - * - * If we haven't been granted anything and are on a resource list, - * then we're blocked/waiting. - * - * If we haven't been granted anything and we're NOT on a resource list, - * then we haven't got a reply yet and don't have a known disposition. - * This happens whenever a lock enqueue is the request that triggers - * recovery. - */ - if (lock->l_granted_mode == lock->l_req_mode) - flags = LDLM_FL_REPLAY | LDLM_FL_BLOCK_GRANTED; - else if (lock->l_granted_mode) - flags = LDLM_FL_REPLAY | LDLM_FL_BLOCK_CONV; - else if (!list_empty(&lock->l_res_link)) - flags = LDLM_FL_REPLAY | LDLM_FL_BLOCK_WAIT; - else - flags = LDLM_FL_REPLAY; - - size = sizeof(*body); - req = ptlrpc_prep_req(imp, LDLM_ENQUEUE, 1, &size, NULL); - if (!req) - RETURN(-ENOMEM); - - /* We're part of recovery, so don't wait for it. */ - req->rq_level = LUSTRE_CONN_RECOVD; - - 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); - - 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); - 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 0f9f4e2..0000000 --- a/lustre/ldlm/ldlm_resource.c +++ /dev/null @@ -1,586 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * Author: Phil Schwan - * 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. - */ - -#define DEBUG_SUBSYSTEM S_LDLM -#ifdef __KERNEL__ -#include -#else -#include -#endif - -#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) -{ - int rc; - ENTRY; - LASSERT(ldlm_ns_proc_dir == NULL); - LASSERT(obd != NULL); - rc = lprocfs_obd_attach(obd, 0); - if (rc) { - CERROR("LProcFS failed in ldlm-init\n"); - RETURN(rc); - } - ldlm_ns_proc_dir = obd->obd_proc_entry; - RETURN(0); -} - -void ldlm_proc_cleanup(struct obd_device *obd) -{ - if (ldlm_ns_proc_dir) { - lprocfs_obd_detach(obd); - ldlm_ns_proc_dir = NULL; - } -} - -#ifdef __KERNEL__ -static int lprocfs_uint_rd(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - unsigned int *temp = (unsigned int *)data; - return snprintf(page, count, "%u\n", *temp); -} - - -#define MAX_STRING_SIZE 128 -void ldlm_proc_namespace(struct ldlm_namespace *ns) -{ - struct lprocfs_vars lock_vars[2]; - char lock_name[MAX_STRING_SIZE + 1]; - - LASSERT(ns != NULL); - LASSERT(ns->ns_name != NULL); - - lock_name[MAX_STRING_SIZE] = '\0'; - - memset(lock_vars, 0, sizeof(lock_vars)); - lock_vars[0].read_fptr = lprocfs_rd_u64; - - lock_vars[0].name = lock_name; - - snprintf(lock_name, MAX_STRING_SIZE, "%s/resource_count", ns->ns_name); - - lock_vars[0].data = &ns->ns_resources; - lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0); - - snprintf(lock_name, MAX_STRING_SIZE, "%s/lock_count", ns->ns_name); - - lock_vars[0].data = &ns->ns_locks; - lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0); - - snprintf(lock_name, MAX_STRING_SIZE, "%s/lock_unused_count", - ns->ns_name); - lock_vars[0].data = &ns->ns_nr_unused; - lock_vars[0].read_fptr = lprocfs_uint_rd; - lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0); -} -#endif -#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) - RETURN(NULL); - - ns->ns_hash = vmalloc(sizeof(*ns->ns_hash) * RES_HASH_SIZE); - if (!ns->ns_hash) - GOTO(out_ns, NULL); - - atomic_add(sizeof(*ns->ns_hash) * RES_HASH_SIZE, &obd_memory); - - OBD_ALLOC(ns->ns_name, strlen(name) + 1); - if (!ns->ns_name) - GOTO(out_hash, NULL); - - 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); -#ifdef __KERNEL__ - ldlm_proc_namespace(ns); -#endif - RETURN(ns); - -out_hash: - POISON(ns->ns_hash, 0x5a, sizeof(*ns->ns_hash) * RES_HASH_SIZE); - vfree(ns->ns_hash); - atomic_sub(sizeof(*ns->ns_hash) * RES_HASH_SIZE, &obd_memory); -out_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. - * This is currently only used for recovery, and we make certain assumptions - * as a result--notably, that we shouldn't cancel locks with refs. -phil - * - * Called with the ns_lock held. */ -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); - - if (local_only && (lock->l_readers || lock->l_writers)) { - /* This is a little bit gross, but much better than the - * alternative: pretend that we got a blocking AST from - * the server, so that when the lock is decref'd, it - * will go away ... */ - lock->l_flags |= LDLM_FL_CBPENDING; - /* ... without sending a CANCEL message. */ - lock->l_flags |= LDLM_FL_LOCAL_ONLY; - /* ... and without calling the cancellation callback */ - lock->l_flags |= LDLM_FL_CANCEL; - LDLM_LOCK_PUT(lock); - continue; - } - - /* 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"); - - ldlm_resource_unlink_lock(lock); - ldlm_lock_destroy(lock); - } - LDLM_LOCK_PUT(lock); - } - EXIT; -} - -int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only) -{ - int i; - - if (ns == NULL) { - CDEBUG(D_INFO, "NULL ns, skipping cleanup\n"); - return ELDLM_OK; - } - - 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); - - POISON(ns->ns_hash, 0x5a, sizeof(*ns->ns_hash) * RES_HASH_SIZE); - vfree(ns->ns_hash /* , sizeof(*ns->ns_hash) * RES_HASH_SIZE */); - atomic_sub(sizeof(*ns->ns_hash) * RES_HASH_SIZE, &obd_memory); - 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, struct ldlm_res_id name) -{ - __u32 hash = 0; - int i; - - for (i = 0; i < RES_NAME_SIZE; i++) - hash += name.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, - struct ldlm_res_id 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, - struct ldlm_res_id name, __u32 type, int create) -{ - struct list_head *bucket, *tmp; - struct ldlm_resource *res = NULL; - ENTRY; - - LASSERT(ns != NULL); - LASSERT(ns->ns_hash != NULL); - - l_lock(&ns->ns_lock); - bucket = ns->ns_hash + ldlm_hash_fn(parent, name); - - list_for_each(tmp, bucket) { - res = list_entry(tmp, struct ldlm_resource, lr_hash); - - if (memcmp(&res->lr_name, &name, sizeof(res->lr_name)) == 0) { - ldlm_resource_getref(res); - l_unlock(&ns->ns_lock); - RETURN(res); - } - } - - if (create) - res = ldlm_resource_add(ns, parent, name, type); - else - res = NULL; - - 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; - ENTRY; - - CDEBUG(D_INFO, "putref res: %p count: %d\n", res, - atomic_read(&res->lr_refcount) - 1); - LASSERT(atomic_read(&res->lr_refcount) > 0); - LASSERT(atomic_read(&res->lr_refcount) < 0x5a5a5a5a); - - if (atomic_dec_and_test(&res->lr_refcount)) { - struct ldlm_namespace *ns = res->lr_namespace; - ENTRY; - - 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_init(&res->lr_hash); - list_del_init(&res->lr_childof); - - POISON(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; - EXIT; - } - - 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); - CDEBUG(D_OTHER, "About to add this lock:\n"); - ldlm_lock_dump(D_OTHER, lock); - - if (lock->l_destroyed) { - CDEBUG(D_OTHER, "Lock destroyed, not adding to resource\n"); - return; - } - - LASSERT(list_empty(&lock->l_res_link)); - - list_add_tail(&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.name[0], - (unsigned long long)res->lr_name.name[1], - (unsigned long long)res->lr_name.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(D_OTHER, 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(D_OTHER, 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(D_OTHER, lock); - } -} diff --git a/lustre/ldlm/ldlm_test.c b/lustre/ldlm/ldlm_test.c deleted file mode 100644 index 6cf1056..0000000 --- a/lustre/ldlm/ldlm_test.c +++ /dev/null @@ -1,648 +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, 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, 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, void *data) -{ - 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; - struct ldlm_res_id res_id = { .name = {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(ns, 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(ns, 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; - struct ldlm_res_id res_id = { .name = {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(ns, 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(ns, 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(ns, 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) -{ - struct ldlm_res_id res_id = { .name = {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(D_OTHER, 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; - struct ldlm_res_id res_id = { .name = {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.name[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.name[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; - unsigned long flags; - ENTRY; - - lock_kernel(); - daemonize(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - sigfillset(¤t->blocked); - recalc_sigpending(); -#else - spin_lock_irqsave(¤t->sigmask_lock, flags); - sigfillset(¤t->blocked); - recalc_sigpending(current); - spin_unlock_irqrestore(¤t->sigmask_lock, flags); -#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 1bcc388..0000000 --- a/lustre/lib/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -EXTRA_DIST = mds_updates.c obd_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 ae490d9..0000000 --- a/lustre/lib/client.c +++ /dev/null @@ -1,406 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2001-2003 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 */ - -#ifdef __KERNEL__ -#include -#else -#include -#endif - -#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; -} - -struct obd_device *client_tgtuuid2obd(struct obd_uuid *tgtuuid) -{ - int i; - - for (i = 0; i < MAX_OBD_DEVICES; i++) { - struct obd_device *obd = &obd_dev[i]; - if ((strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) == 0) || - (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) == 0)) { - struct client_obd *cli = &obd->u.cli; - if (strncmp(tgtuuid->uuid, cli->cl_target_uuid.uuid, - sizeof(cli->cl_target_uuid.uuid)) == 0) - return obd; - } - } - - return NULL; -} - -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; - struct obd_uuid 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.uuid, data->ioc_inlbuf1, data->ioc_inllen1); - memcpy(server_uuid.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); -#if !defined(__KERNEL__) || (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - cli->cl_sandev = 0; -#else - cli->cl_sandev.value = 0; -#endif - - RETURN(0); -} - -#ifdef __KERNEL__ -/* convert a pathname into a kdev_t */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -static kdev_t path2dev(char *path) -{ - struct dentry *dentry; - struct nameidata nd; - kdev_t dev = 0; - - if (!path_init(path, LOOKUP_FOLLOW, &nd)) - return 0; - - if (path_walk(path, &nd)) - return 0; - - dentry = nd.dentry; - if (dentry->d_inode && !is_bad_inode(dentry->d_inode) && - S_ISBLK(dentry->d_inode->i_mode)) - dev = dentry->d_inode->i_rdev; - path_release(&nd); - - return dev; -} -#else -static int path2dev(char *path) -{ - struct dentry *dentry; - struct nameidata nd; - int dev = 0; - - if (!path_init(path, LOOKUP_FOLLOW, &nd)) - return 0; - - if (path_walk(path, &nd)) - return 0; - - dentry = nd.dentry; - if (dentry->d_inode && !is_bad_inode(dentry->d_inode) && - S_ISBLK(dentry->d_inode->i_mode)) -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - dev = dentry->d_inode->i_rdev; -#else - dev = dentry->d_inode->i_rdev.value; -#endif - path_release(&nd); - - return dev; -} -#endif - -int client_sanobd_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - struct obd_ioctl_data* data = buf; - struct client_obd *cli = &obddev->u.cli; - struct obd_import *imp = &cli->cl_import; - struct obd_uuid server_uuid; - ENTRY; - - 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); - } - - if (data->ioc_inllen3 < 1) { - CERROR("setup requires a SAN device pathname\n"); - RETURN(-EINVAL); - } - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - cli->cl_sandev = path2dev(data->ioc_inlbuf3); - if (!cli->cl_sandev) { - CERROR("%s seems not a valid SAN device\n", data->ioc_inlbuf3); - RETURN(-EINVAL); - } -#else - cli->cl_sandev.value = path2dev(data->ioc_inlbuf3); - if (!cli->cl_sandev.value) { - CERROR("%s seems not a valid SAN device\n", data->ioc_inlbuf3); - RETURN(-EINVAL); - } -#endif - - sema_init(&cli->cl_sem, 1); - cli->cl_conn_count = 0; - memcpy(cli->cl_target_uuid.uuid, data->ioc_inlbuf1, data->ioc_inllen1); - memcpy(server_uuid.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(OST_REQUEST_PORTAL, OSC_REPLY_PORTAL, - "sanosc", &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); - - RETURN(0); -} -#endif - -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); - - return 0; -} - -int client_obd_connect(struct lustre_handle *conn, struct obd_device *obd, - struct obd_uuid *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.uuid, obd->obd_uuid.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; - int msg_flags; - - ENTRY; - down(&cli->cl_sem); - rc = class_connect(conn, obd, cluuid); - if (rc) - 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_max_transno = 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); - - msg_flags = lustre_msg_get_op_flags(request->rq_repmsg); - if (rq_opc == MDS_CONNECT || msg_flags & MSG_CONNECT_REPLAYABLE) { - imp->imp_flags |= IMP_REPLAYABLE; - CDEBUG(D_HA, "connected to replayable target: %s\n", cli->cl_target_uuid.uuid); - } - 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; -out_disco: - cli->cl_conn_count--; - class_disconnect(conn); - } -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_no_disconnect, rc = 0); - - if (obd->obd_namespace != NULL) { - ldlm_cli_cancel_unused(obd->obd_namespace, NULL, 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_req, 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); - list_del_init(&cli->cl_import.imp_chain); - out_no_disconnect: - err = class_disconnect(conn); - if (!rc && err) - rc = err; - out_sem: - up(&cli->cl_sem); - RETURN(rc); -} diff --git a/lustre/lib/mds_updates.c b/lustre/lib/mds_updates.c deleted file mode 100644 index aa666ad4..0000000 --- a/lustre/lib/mds_updates.c +++ /dev/null @@ -1,604 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Lustre Lite Update Records - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#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_FLBLOCKS | - OBD_MD_FLUID | OBD_MD_FLGID | OBD_MD_FLTYPE | OBD_MD_FLMODE | - OBD_MD_FLNLINK | OBD_MD_FLGENER; - - /* The MDS file size isn't authoritative for regular files, so don't - * even pretend. */ - if (S_ISREG(inode->i_mode)) - b->valid &= ~(OBD_MD_FLSIZE | OBD_MD_FLBLOCKS); - - b->ino = HTON__u32(inode->i_ino); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - b->atime = HTON__u32(inode->i_atime); - b->mtime = HTON__u32(inode->i_mtime); - b->ctime = HTON__u32(inode->i_ctime); -#else - b->atime = HTON__u32(inode->i_atime.tv_sec); - b->mtime = HTON__u32(inode->i_mtime.tv_sec); - b->ctime = HTON__u32(inode->i_ctime.tv_sec); -#endif - b->mode = HTON__u32(inode->i_mode); - b->size = HTON__u64(inode->i_size); - b->blocks = HTON__u64(inode->i_blocks); - 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); - b->suppgid = HTON__u32(-1); -} - - -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); - b->suppgid = HTON__u32(b->suppgid); -} - -void mds_getattr_pack(struct ptlrpc_request *req, int valid, int offset, - int flags, - 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); - b->valid = HTON__u32(valid); - b->flags = HTON__u32(flags); - if (in_group_p(inode->i_gid)) - b->suppgid = HTON__u32(inode->i_gid); - else - b->suppgid = HTON__u32(-1); - - 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, __u64 xid) -{ - 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); - b->suppgid = HTON__u32(-1); - b->blocks = HTON__u64(xid); -} - - -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); - - 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); - if (in_group_p(dir->i_gid)) - rec->cr_suppgid = HTON__u32(dir->i_gid); - else - rec->cr_suppgid = HTON__u32(-1); - - 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); - } -} -/* packing of MDS records */ -void mds_open_pack(struct ptlrpc_request *req, int offset, struct inode *dir, - __u32 mode, __u64 rdev, __u32 uid, __u32 gid, __u64 time, - __u32 flags, - 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_OPEN); - 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_flags = HTON__u32(flags); - rec->cr_rdev = HTON__u64(rdev); - rec->cr_uid = HTON__u32(uid); - rec->cr_gid = HTON__u32(gid); - rec->cr_time = HTON__u64(time); - if (in_group_p(dir->i_gid)) - rec->cr_suppgid = HTON__u32(dir->i_gid); - else - rec->cr_suppgid = HTON__u32(-1); - - 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, - struct inode *inode, struct iattr *iattr, - void *ea, int ealen) -{ - struct mds_rec_setattr *rec = lustre_msg_buf(req->rq_reqmsg, 0); - - 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); - - if (iattr) { - 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); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - rec->sa_atime = HTON__u64(iattr->ia_atime); - rec->sa_mtime = HTON__u64(iattr->ia_mtime); - rec->sa_ctime = HTON__u64(iattr->ia_ctime); -#else - rec->sa_atime = HTON__u64(iattr->ia_atime.tv_sec); - rec->sa_mtime = HTON__u64(iattr->ia_mtime.tv_sec); - rec->sa_ctime = HTON__u64(iattr->ia_ctime.tv_sec); -#endif - rec->sa_attr_flags = HTON__u32(iattr->ia_attr_flags); - - if ((iattr->ia_valid & ATTR_GID) && in_group_p(iattr->ia_gid)) - rec->sa_suppgid = HTON__u32(iattr->ia_gid); - else if ((iattr->ia_valid & ATTR_MODE) && - in_group_p(inode->i_gid)) - rec->sa_suppgid = HTON__u32(inode->i_gid); - else - rec->sa_suppgid = HTON__u32(-1); - } - - if (ealen) - memcpy(lustre_msg_buf(req->rq_reqmsg, 1), ea, ealen); -} - -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); - if (in_group_p(inode->i_gid)) - rec->ul_suppgid = HTON__u32(inode->i_gid); - else - rec->ul_suppgid = HTON__u32(-1); - 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); - if (in_group_p(dir->i_gid)) - rec->lk_suppgid = HTON__u32(dir->i_gid); - else - rec->lk_suppgid = HTON__u32(-1); - 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); - if (in_group_p(srcdir->i_gid)) - rec->rn_suppgid1 = HTON__u32(srcdir->i_gid); - else - rec->rn_suppgid1 = HTON__u32(-1); - if (in_group_p(tgtdir->i_gid)) - rec->rn_suppgid2 = HTON__u32(tgtdir->i_gid); - else - rec->rn_suppgid2 = HTON__u32(-1); - 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->blocks = NTOH__u64(b->blocks); - 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); - b->suppgid = NTOH__u32(b->suppgid); -} - -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_suppgid1 = NTOH__u32(rec->sa_suppgid); - r->ur_suppgid2 = NTOH__u32(-1); - 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); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - attr->ia_atime = NTOH__u64(rec->sa_atime); - attr->ia_mtime = NTOH__u64(rec->sa_mtime); - attr->ia_ctime = NTOH__u64(rec->sa_ctime); -#else - attr->ia_atime.tv_sec = NTOH__u64(rec->sa_atime); - attr->ia_mtime.tv_sec = NTOH__u64(rec->sa_mtime); - attr->ia_ctime.tv_sec = NTOH__u64(rec->sa_ctime); -#endif - 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_flags = NTOH__u32(rec->cr_flags); - r->ur_suppgid1 = NTOH__u32(rec->cr_suppgid); - r->ur_suppgid2 = NTOH__u32(-1); - - 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_suppgid1 = NTOH__u32(rec->lk_suppgid); - r->ur_suppgid2 = NTOH__u32(-1); - 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_suppgid1 = NTOH__u32(rec->ul_suppgid); - r->ur_suppgid2 = NTOH__u32(-1); - 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_suppgid1 = NTOH__u32(rec->rn_suppgid1); - r->ur_suppgid2 = NTOH__u32(rec->rn_suppgid2); - 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, - [REINT_OPEN] mds_create_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) { - LBUG(); - 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 c77b5b8..0000000 --- a/lustre/lib/obd_pack.c +++ /dev/null @@ -1,83 +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 -#ifndef __KERNEL__ -#include -#endif - -#include -#include - -void ost_pack_ioo(struct obd_ioobj **tmp, struct lov_stripe_md *lsm,int bufcnt) -{ - struct obd_ioobj *ioo = *tmp; - void *p = *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 = p + sizeof(*ioo); -} - -void ost_unpack_ioo(struct obd_ioobj **tmp, struct obd_ioobj **ioop) -{ - void *p = *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 = p + 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 c0d4f31..0000000 --- a/lustre/lib/simple.c +++ /dev/null @@ -1,270 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * Author: Peter Braam - * Aurhot: 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 - -#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) LASSERT((magic) == OBD_RUN_CTXT_MAGIC) -#define ASSERT_NOT_KERNEL_CTXT(msg) LASSERT(!segment_eq(get_fs(), get_ds())) -#define ASSERT_KERNEL_CTXT(msg) LASSERT(segment_eq(get_fs(), get_ds())) -#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:d%d:i%d (%*s), pwdmnt %p:%d\n", - save, current, current->fs, current->fs->pwd, - atomic_read(¤t->fs->pwd->d_count), - atomic_read(¤t->fs->pwd->d_inode->i_count), - current->fs->pwd->d_name.len, current->fs->pwd->d_name.name, - current->fs->pwdmnt, - atomic_read(¤t->fs->pwdmnt->mnt_count)); - */ - - save->fs = get_fs(); - LASSERT(atomic_read(¤t->fs->pwd->d_count)); - LASSERT(atomic_read(&new_ctx->pwd->d_count)); - 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; - if (uc->ouc_suppgid1 != -1) - current->groups[current->ngroups++] = uc->ouc_suppgid1; - if (uc->ouc_suppgid2 != -1) - current->groups[current->ngroups++] = uc->ouc_suppgid2; - } - 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:d%d:i%d (%*s), pwdmnt %p:%d\n", - new_ctx, current, current->fs, current->fs->pwd, - atomic_read(¤t->fs->pwd->d_count), - atomic_read(¤t->fs->pwd->d_inode->i_count), - current->fs->pwd->d_name.len, current->fs->pwd->d_name.name, - current->fs->pwdmnt, - atomic_read(¤t->fs->pwdmnt->mnt_count)); - */ -} - -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:d%d:i%d (%*s), pwdmnt %p:%d\n", - new_ctx, current, current->fs, current->fs->pwd, - atomic_read(¤t->fs->pwd->d_count), - atomic_read(¤t->fs->pwd->d_inode->i_count), - current->fs->pwd->d_name.len, current->fs->pwd->d_name.name, - current->fs->pwdmnt, - atomic_read(¤t->fs->pwdmnt->mnt_count)); - */ - - LASSERT(current->fs->pwd == new_ctx->pwd); - LASSERT(current->fs->pwdmnt == new_ctx->pwdmnt); - - set_fs(saved->fs); - set_fs_pwd(current->fs, saved->pwdmnt, saved->pwd); - - dput(saved->pwd); - mntput(saved->pwdmnt); - if (uc) { - current->fsuid = saved->fsuid; - current->fsgid = saved->fsgid; - current->cap_effective = saved->cap; - - if (uc->ouc_suppgid1 != -1) - current->ngroups--; - if (uc->ouc_suppgid2 != -1) - current->ngroups--; - } - - /* - CDEBUG(D_INFO, - "= pop %p->%p = cur fs %p pwd %p:d%d:i%d (%*s), pwdmnt %p:%d\n", - saved, current, current->fs, current->fs->pwd, - atomic_read(¤t->fs->pwd->d_count), - atomic_read(¤t->fs->pwd->d_inode->i_count), - current->fs->pwd->d_name.len, current->fs->pwd->d_name.name, - current->fs->pwdmnt, - atomic_read(¤t->fs->pwdmnt->mnt_count)); - */ -} - -/* 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); - - dchild = lookup_one_len(name, dir, strlen(name)); - if (IS_ERR(dchild)) - GOTO(out_up, dchild); - - if (dchild->d_inode) { - if ((dchild->d_inode->i_mode & S_IFMT) != S_IFREG) - GOTO(out_err, err = -EEXIST); - - GOTO(out_up, dchild); - } - - err = vfs_create(dir->d_inode, dchild, (mode & ~S_IFMT) | S_IFREG); - if (err) - GOTO(out_err, err); - - RETURN(dchild); - -out_err: - dput(dchild); - dchild = ERR_PTR(err); -out_up: - 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); - dchild = lookup_one_len(name, dir, strlen(name)); - if (IS_ERR(dchild)) - GOTO(out_up, dchild); - - if (dchild->d_inode) { - if (!S_ISDIR(dchild->d_inode->i_mode)) - GOTO(out_err, err = -ENOTDIR); - - GOTO(out_up, dchild); - } - - err = vfs_mkdir(dir->d_inode, dchild, mode); - if (err) - GOTO(out_err, err); - - RETURN(dchild); - -out_err: - dput(dchild); - dchild = ERR_PTR(err); -out_up: - 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) -{ - ENTRY; - ASSERT_KERNEL_CTXT("kernel doing write outside kernel context\n"); - if (!file) - RETURN(-ENOENT); - if (!file->f_op) - RETURN(-ENOSYS); - if (!off) - RETURN(-EINVAL); - - 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) -{ - ENTRY; - 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 590ae4b..0000000 --- a/lustre/lib/target.c +++ /dev/null @@ -1,523 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2001-2003 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_reconnect(struct lustre_handle *conn, struct obd_export *exp, - struct obd_uuid *cluuid) -{ - 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->uuid); - conn->addr = (__u64) (unsigned long)exp; - conn->cookie = exp->exp_cookie; - RETURN(EALREADY); - } else { - CERROR("%s reconnecting from %s, " - "handle mismatch (ours "LPX64"/"LPX64", " - "theirs "LPX64"/"LPX64")\n", cluuid->uuid, - exp->exp_connection->c_remote_uuid.uuid, - hdl->addr, - hdl->cookie, conn->addr, conn->cookie); - /* XXX disconnect them here? */ - memset(conn, 0, sizeof *conn); - /* This is a little scary, but right now we build this - * file separately into each server module, so I won't - * go _immediately_ to hell. - */ - RETURN(-EALREADY); - } - } - - conn->addr = (__u64) (unsigned long)exp; - conn->cookie = exp->exp_cookie; - CDEBUG(D_INFO, "existing export for UUID '%s' at %p\n", cluuid->uuid, exp); - CDEBUG(D_IOCTL,"connect: addr %Lx cookie %Lx\n", - (long long)conn->addr, (long long)conn->cookie); - RETURN(0); -} - - -int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler) -{ - struct obd_device *target; - struct obd_export *export = NULL; - struct obd_import *dlmimp; - struct lustre_handle conn; - struct obd_uuid tgtuuid; - struct obd_uuid cluuid; - struct list_head *p; - int rc, i; - ENTRY; - - if (req->rq_reqmsg->buflens[0] > 37) { - CERROR("bad target UUID for connect\n"); - GOTO(out, rc = -EINVAL); - } - obd_str2uuid(&tgtuuid, lustre_msg_buf(req->rq_reqmsg, 0)); - - if (req->rq_reqmsg->buflens[1] > 37) { - CERROR("bad client UUID for connect\n"); - GOTO(out, rc = -EINVAL); - } - obd_str2uuid(&cluuid, lustre_msg_buf(req->rq_reqmsg, 1)); - - i = class_uuid2dev(&tgtuuid); - if (i == -1) { - CERROR("UUID '%s' not found for connect\n", tgtuuid.uuid); - GOTO(out, rc = -ENODEV); - } - - target = &obd_dev[i]; - if (!target) - GOTO(out, rc = -ENODEV); - - spin_lock_bh(&target->obd_processing_task_lock); - if (target->obd_flags & OBD_ABORT_RECOVERY) - target_abort_recovery(target); - spin_unlock_bh(&target->obd_processing_task_lock); - - conn.addr = req->rq_reqmsg->addr; - conn.cookie = req->rq_reqmsg->cookie; - - rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - GOTO(out, rc); - - /* lctl gets a backstage, all-access pass. */ - if (!strcmp(cluuid.uuid, "OBD_CLASS_UUID")) - goto dont_check_exports; - - spin_lock(&target->obd_dev_lock); - list_for_each(p, &target->obd_exports) { - export = list_entry(p, struct obd_export, exp_obd_chain); - if (!memcmp(&cluuid, &export->exp_client_uuid, - sizeof(export->exp_client_uuid))) { - spin_unlock(&target->obd_dev_lock); - LASSERT(export->exp_obd == target); - - rc = target_handle_reconnect(&conn, export, &cluuid); - break; - } - export = NULL; - } - /* If we found an export, we already unlocked. */ - if (!export) - spin_unlock(&target->obd_dev_lock); - - /* Tell the client if we're in recovery. */ - /* If this is the first client, start the recovery timer */ - if (target->obd_flags & OBD_RECOVERING) { - lustre_msg_add_op_flags(req->rq_repmsg, MSG_CONNECT_RECOVERING); - target_start_recovery_timer(target, handler); - } - - /* Tell the client if we support replayable requests */ - if (target->obd_flags & OBD_REPLAYABLE) - lustre_msg_add_op_flags(req->rq_repmsg, MSG_CONNECT_REPLAYABLE); - - if (!export) { - if (target->obd_flags & OBD_RECOVERING) { - CERROR("denying connection for new client %s: " - "in recovery\n", cluuid.uuid); - rc = -EBUSY; - } else { - dont_check_exports: - rc = obd_connect(&conn, target, &cluuid, ptlrpc_recovd, - target_revoke_connection); - } - } - - /* If all else goes well, this is our RPC return code. */ - req->rq_status = 0; - - if (rc && rc != EALREADY) - 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); - - if (rc == EALREADY) { - /* We indicate the reconnection in a flag, not an error code. */ - lustre_msg_add_op_flags(req->rq_repmsg, MSG_CONNECT_RECONNECT); - GOTO(out, rc = 0); - } - - 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; - dlmimp->imp_recover = NULL; - INIT_LIST_HEAD(&dlmimp->imp_replay_list); - INIT_LIST_HEAD(&dlmimp->imp_sending_list); - INIT_LIST_HEAD(&dlmimp->imp_delayed_list); - spin_lock_init(&dlmimp->imp_lock); - dlmimp->imp_level = LUSTRE_CONN_FULL; -out: - if (rc) - 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); - req->rq_export = NULL; - 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); - - CDEBUG(D_HA, "disconnecting export %p/%s\n", - exp, exp->exp_client_uuid.uuid); - 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); -} - -/* - * Recovery functions - */ - -static void abort_delayed_replies(struct obd_device *obd) -{ - struct ptlrpc_request *req; - struct list_head *tmp, *n; - list_for_each_safe(tmp, n, &obd->obd_delayed_reply_queue) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - DEBUG_REQ(D_ERROR, req, "aborted:"); - req->rq_status = -ENOTCONN; - req->rq_type = PTL_RPC_MSG_ERR; - ptlrpc_reply(req->rq_svc, req); - list_del(&req->rq_list); - OBD_FREE(req, sizeof *req); - } -} - -void target_abort_recovery(void *data) -{ - struct obd_device *obd = data; - CERROR("disconnecting clients and aborting recovery\n"); - obd->obd_recoverable_clients = 0; - obd->obd_flags &= ~(OBD_RECOVERING | OBD_ABORT_RECOVERY); - abort_delayed_replies(obd); - spin_unlock_bh(&obd->obd_processing_task_lock); - class_disconnect_all(obd); - spin_lock_bh(&obd->obd_processing_task_lock); -} - -static void target_recovery_expired(unsigned long castmeharder) -{ - struct obd_device *obd = (struct obd_device *)castmeharder; - CERROR("recovery timed out, aborting\n"); - spin_lock_bh(&obd->obd_processing_task_lock); - obd->obd_flags |= OBD_ABORT_RECOVERY; - wake_up(&obd->obd_next_transno_waitq); - spin_unlock_bh(&obd->obd_processing_task_lock); -} - -static void reset_recovery_timer(struct obd_device *obd) -{ - CDEBUG(D_ERROR, "timer will expire in %ld seconds\n", - OBD_RECOVERY_TIMEOUT / HZ); - mod_timer(&obd->obd_recovery_timer, jiffies + OBD_RECOVERY_TIMEOUT); -} - - -/* Only start it the first time called */ -void target_start_recovery_timer(struct obd_device *obd, svc_handler_t handler) -{ - spin_lock_bh(&obd->obd_processing_task_lock); - if (obd->obd_recovery_handler) { - spin_unlock_bh(&obd->obd_processing_task_lock); - return; - } - CERROR("%s: starting recovery timer\n", obd->obd_name); - obd->obd_recovery_handler = handler; - obd->obd_recovery_timer.function = target_recovery_expired; - obd->obd_recovery_timer.data = (unsigned long)obd; - init_timer(&obd->obd_recovery_timer); - spin_unlock_bh(&obd->obd_processing_task_lock); - - reset_recovery_timer(obd); -} - -static void cancel_recovery_timer(struct obd_device *obd) -{ - del_timer(&obd->obd_recovery_timer); -} - -static int check_for_next_transno(struct obd_device *obd) -{ - struct ptlrpc_request *req; - req = list_entry(obd->obd_recovery_queue.next, - struct ptlrpc_request, rq_list); - LASSERT(req->rq_reqmsg->transno >= obd->obd_next_recovery_transno); - - return req->rq_reqmsg->transno == obd->obd_next_recovery_transno || - (obd->obd_flags & OBD_RECOVERING) == 0; -} - -static void process_recovery_queue(struct obd_device *obd) -{ - struct ptlrpc_request *req; - int aborted = 0; - ENTRY; - - for (;;) { - spin_lock_bh(&obd->obd_processing_task_lock); - LASSERT(obd->obd_processing_task == current->pid); - req = list_entry(obd->obd_recovery_queue.next, - struct ptlrpc_request, rq_list); - - if (req->rq_reqmsg->transno != obd->obd_next_recovery_transno) { - spin_unlock_bh(&obd->obd_processing_task_lock); - CDEBUG(D_HA, "Waiting for transno "LPD64" (1st is " - LPD64")\n", - obd->obd_next_recovery_transno, - req->rq_reqmsg->transno); - wait_event(obd->obd_next_transno_waitq, - check_for_next_transno(obd)); - spin_lock_bh(&obd->obd_processing_task_lock); - if (obd->obd_flags & OBD_ABORT_RECOVERY) { - target_abort_recovery(obd); - aborted = 1; - } - spin_unlock_bh(&obd->obd_processing_task_lock); - if (aborted) - return; - continue; - } - list_del_init(&req->rq_list); - spin_unlock_bh(&obd->obd_processing_task_lock); - - DEBUG_REQ(D_ERROR, req, "processing: "); - (void)obd->obd_recovery_handler(req); - reset_recovery_timer(obd); -#warning FIXME: mds_fsync_super(mds->mds_sb); - OBD_FREE(req, sizeof *req); - spin_lock_bh(&obd->obd_processing_task_lock); - obd->obd_next_recovery_transno++; - if (list_empty(&obd->obd_recovery_queue)) { - obd->obd_processing_task = 0; - spin_unlock_bh(&obd->obd_processing_task_lock); - break; - } - spin_unlock_bh(&obd->obd_processing_task_lock); - } - EXIT; -} - -int target_queue_recovery_request(struct ptlrpc_request *req, - struct obd_device *obd) -{ - struct list_head *tmp; - int inserted = 0; - __u64 transno = req->rq_reqmsg->transno; - struct ptlrpc_request *saved_req; - - if (!transno) { - INIT_LIST_HEAD(&req->rq_list); - DEBUG_REQ(D_HA, req, "not queueing"); - return 1; - } - - spin_lock_bh(&obd->obd_processing_task_lock); - - if (obd->obd_processing_task == current->pid) { - /* Processing the queue right now, don't re-add. */ - LASSERT(list_empty(&req->rq_list)); - spin_unlock_bh(&obd->obd_processing_task_lock); - return 1; - } - - OBD_ALLOC(saved_req, sizeof *saved_req); - if (!saved_req) - LBUG(); - memcpy(saved_req, req, sizeof *req); - req = saved_req; - INIT_LIST_HEAD(&req->rq_list); - - /* XXX O(n^2) */ - list_for_each(tmp, &obd->obd_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, &obd->obd_recovery_queue); - } - - if (obd->obd_processing_task != 0) { - /* Someone else is processing this queue, we'll leave it to - * them. - */ - if (transno == obd->obd_next_recovery_transno) - wake_up(&obd->obd_next_transno_waitq); - spin_unlock_bh(&obd->obd_processing_task_lock); - return 0; - } - - /* Nobody is processing, and we know there's (at least) one to process - * now, so we'll do the honours. - */ - obd->obd_processing_task = current->pid; - spin_unlock_bh(&obd->obd_processing_task_lock); - - process_recovery_queue(obd); - return 0; -} - -struct obd_device * target_req2obd(struct ptlrpc_request *req) -{ - return req->rq_export->exp_obd; -} - -int target_queue_final_reply(struct ptlrpc_request *req, int rc) -{ - struct obd_device *obd = target_req2obd(req); - struct ptlrpc_request *saved_req; - - spin_lock_bh(&obd->obd_processing_task_lock); - 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; - } - - LASSERT(list_empty(&req->rq_list)); - OBD_ALLOC(saved_req, sizeof *saved_req); - memcpy(saved_req, req, sizeof *saved_req); - req = saved_req; - list_add(&req->rq_list, &obd->obd_delayed_reply_queue); - if (--obd->obd_recoverable_clients == 0) { - struct list_head *tmp, *n; - ldlm_reprocess_all_ns(req->rq_export->exp_obd->obd_namespace); - CDEBUG(D_ERROR, - "all clients recovered, sending delayed replies\n"); - obd->obd_flags &= ~OBD_RECOVERING; - list_for_each_safe(tmp, n, &obd->obd_delayed_reply_queue) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - DEBUG_REQ(D_ERROR, req, "delayed:"); - ptlrpc_reply(req->rq_svc, req); - list_del(&req->rq_list); - OBD_FREE(req, sizeof *req); - } - cancel_recovery_timer(obd); - } else { - CERROR("%d recoverable clients remain\n", - obd->obd_recoverable_clients); - } - - spin_unlock_bh(&obd->obd_processing_task_lock); - return 1; -} diff --git a/lustre/liblustre/.cvsignore b/lustre/liblustre/.cvsignore deleted file mode 100644 index fb1a186..0000000 --- a/lustre/liblustre/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS -libtest diff --git a/lustre/liblustre/Makefile.am b/lustre/liblustre/Makefile.am deleted file mode 100644 index c761a22..0000000 --- a/lustre/liblustre/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) -LIBS= -LLIBS= ../lov/liblov.a ../obdecho/libobdecho.a ../osc/libosc.a ../ldlm/libldlm.a ../ptlrpc/libptlrpc.a ../obdclass/liblustreclass.a - -libtest_LDADD := $(LIBREADLINE) $(LLIBS) \ - $(PORTALS)/user/procbridge/libprocbridge.a $(PORTALS)/user/tcpnal/libtcpnal.a \ - $(PORTALS)/user/util/libtcpnalutil.a $(PORTALS)/user/$(PORTALS)/api/libptlapi.a \ - $(PORTALS)/lib/libptllib.a -lptlctl -lpthread -lefence -bin_PROGRAMS = libtest -libtest_SOURCES = libtest.c - -include $(top_srcdir)/Rules diff --git a/lustre/liblustre/libtest.c b/lustre/liblustre/libtest.c deleted file mode 100644 index 2941398..0000000 --- a/lustre/liblustre/libtest.c +++ /dev/null @@ -1,114 +0,0 @@ -#include -#include -#include -#include - -#include /* needed for ptpctl.h */ -#include /* needed for parse_dump */ - - -#include -#include -#include -#include <../user/procbridge/procbridge.h> - -ptl_handle_ni_t tcpnal_ni; - -struct pingcli_args { - ptl_nid_t mynid; - ptl_nid_t nid; - ptl_pid_t port; - int count; - int size; -}; - -struct task_struct *current; - -struct obd_class_user_state ocus; - -/* portals interfaces */ -inline const ptl_handle_ni_t * -kportal_get_ni (int nal) -{ - return &tcpnal_ni; -} - -inline void -kportal_put_ni (int nal) -{ - return; -} - -void init_current(int argc, char **argv) -{ - current = malloc(sizeof(*current)); - strncpy(current->comm, argv[0], sizeof(current->comm)); - current->pid = getpid(); - -} - -ptl_nid_t tcpnal_mynid; - -int init_lib_portals(struct pingcli_args *args) -{ - int rc; - - PtlInit(); - tcpnal_mynid = args->mynid; - rc = PtlNIInit(procbridge_interface, 0, 0, 0, &tcpnal_ni); - if (rc != 0) { - CERROR("ksocknal: PtlNIInit failed: error %d\n", rc); - PtlFini(); - RETURN (rc); - } - PtlNIDebug(tcpnal_ni, ~0); - return rc; -} - -extern int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd, unsigned long arg); - - -int lib_ioctl(int dev_id, int opc, void * ptr) -{ - - if (dev_id == OBD_DEV_ID) { - struct obd_ioctl_data *ioc = ptr; - class_handle_ioctl(&ocus, opc, (unsigned long)ptr); - - /* you _may_ need to call obd_ioctl_unpack or some - other verification function if you want to use ioc - directly here */ - printf ("processing ioctl cmd: %x buf len: %d\n", - opc, ioc->ioc_len); - } - return (0); -} - -int main(int argc, char **argv) -{ - struct pingcli_args *args; - args= malloc(sizeof(*args)); - if (!args) { - printf("Malloc error\n"); - exit(1); - } - - args->mynid = ntohl (inet_addr (argv[1])); - INIT_LIST_HEAD(&ocus.ocus_conns); - - init_current(argc, argv); - init_obdclass(); - init_lib_portals(args); - ptlrpc_init(); - ldlm_init(); - osc_init(); - echo_client_init(); - /* XXX need mdc_getlovinfo before lov_init can work.. */ - // lov_init(); - - parse_dump("/tmp/DUMP_FILE", lib_ioctl); - - printf("Hello\n"); - return 0; -} - diff --git a/lustre/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 c536a0a..0000000 --- a/lustre/llite/Makefile.am +++ /dev/null @@ -1,16 +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 - -llite_SOURCES = dcache.c commit_callback.c super.c rw.c super25.c -llite_SOURCES += file.c dir.c sysctl.c symlink.c -llite_SOURCES += recover.c namei.c lproc_llite.c - -include $(top_srcdir)/Rules diff --git a/lustre/llite/commit_callback.c b/lustre/llite/commit_callback.c deleted file mode 100644 index 0e17c1a..0000000 --- a/lustre/llite/commit_callback.c +++ /dev/null @@ -1,137 +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); - - EXIT; - 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; - unsigned long flags; - ENTRY; - - lock_kernel(); - daemonize(); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - spin_lock_irqsave(¤t->sigmask_lock, flags); - sigfillset(¤t->blocked); - our_recalc_sigpending(current); - spin_unlock_irqrestore(¤t->sigmask_lock, flags); -#else - sigfillset(¤t->blocked); - our_recalc_sigpending(current); -#endif - - sprintf(current->comm, "lustre_commitcbd"); - unlock_kernel(); - - /* Record that the thread is running */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - sbi->ll_commitcbd_waketime = CURRENT_TIME; -#else - sbi->ll_commitcbd_waketime = CURRENT_TIME.tv_sec; -#endif - 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 41c68d9..0000000 --- a/lustre/llite/dcache.c +++ /dev/null @@ -1,224 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2001-2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include -#include -#include - -/* should NOT be called with the dcache lock, see fs/dcache.c */ -void ll_release(struct dentry *de) -{ - ENTRY; - OBD_FREE(de->d_fsdata, sizeof(struct ll_dentry_data)); - EXIT; -} - -void ll_set_dd(struct dentry *de) -{ - ENTRY; - LASSERT(de != NULL); - - lock_kernel(); - - if (de->d_fsdata == NULL) { - OBD_ALLOC(de->d_fsdata, sizeof(struct ll_dentry_data)); - sema_init(&ll_d2d(de)->lld_it_sem, 1); - } - - unlock_kernel(); - - EXIT; -} - -void ll_intent_release(struct dentry *de, struct lookup_intent *it) -{ - struct lustre_handle *handle; - ENTRY; - - LASSERT(ll_d2d(de) != NULL); - - if (it->it_lock_mode) { - handle = (struct lustre_handle *)it->it_lock_handle; - ldlm_lock_decref(handle, it->it_lock_mode); - - /* intent_release may be called multiple times, from - this thread 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); - else - CERROR("STRANGE intent release: %p %p\n", de->d_it, 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) -{ - struct mds_body *body; - struct lov_mds_md *lmm = NULL; - int rc = 0; - ENTRY; - - if (!(flag & LL_LOOKUP_NEGATIVE)) { - body = lustre_msg_buf(request->rq_repmsg, offset); - if (body->valid & OBD_MD_FLEASIZE) - lmm = lustre_msg_buf(request->rq_repmsg, offset + 1); - ll_update_inode((*de)->d_inode, body, lmm); - mdc_lock_set_inode((struct lustre_handle *)it->it_lock_handle, - (*de)->d_inode); - } else - rc = -ENOENT; - - ptlrpc_req_finished(request); - RETURN(rc); -} - -int ll_have_md_lock(struct dentry *de) -{ - struct ll_sb_info *sbi = ll_s2sbi(de->d_sb); - struct lustre_handle lockh; - struct ldlm_res_id res_id = { .name = {0} }; - struct obd_device *obddev; - ENTRY; - - if (!de->d_inode) - RETURN(0); - - obddev = class_conn2obd(&sbi->ll_mdc_conn); - res_id.name[0] = de->d_inode->i_ino; - res_id.name[1] = de->d_inode->i_generation; - - CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id.name[0]); - - if (ldlm_lock_match(obddev->obd_namespace, LDLM_FL_BLOCK_GRANTED, - &res_id, LDLM_PLAIN, NULL, 0, LCK_PR, &lockh)) { - ldlm_lock_decref(&lockh, LCK_PR); - RETURN(1); - } - - if (ldlm_lock_match(obddev->obd_namespace, LDLM_FL_BLOCK_GRANTED, - &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 || it->it_op == IT_GETATTR) { - /* We could just return 1 immediately, but since we should only - * be called in revalidate2 if we already have a lock, let's - * verify that. */ - struct inode *inode = de->d_inode; - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct obd_device *obddev = class_conn2obd(&sbi->ll_mdc_conn); - struct ldlm_res_id res_id = - { .name = {inode->i_ino, (__u64)inode->i_generation} }; - struct lustre_handle lockh; - rc = ldlm_lock_match(obddev->obd_namespace, - LDLM_FL_BLOCK_GRANTED, &res_id, - LDLM_PLAIN, NULL, 0, LCK_PR, &lockh); - if (rc) { - de->d_flags &= ~DCACHE_LUSTRE_INVALID; - if (it && it->it_op == IT_GETATTR) { - memcpy(it->it_lock_handle, &lockh, - sizeof(lockh)); - it->it_lock_mode = LCK_PR; - LL_SAVE_INTENT(de, it); - } else { - ldlm_lock_decref(&lockh, LCK_PR); - } - RETURN(1); - } - rc = ldlm_lock_match(obddev->obd_namespace, - LDLM_FL_BLOCK_GRANTED, &res_id, - LDLM_PLAIN, NULL, 0, LCK_PW, &lockh); - if (rc) { - de->d_flags &= ~DCACHE_LUSTRE_INVALID; - if (it && it->it_op == IT_GETATTR) { - memcpy(it->it_lock_handle, &lockh, - sizeof(lockh)); - it->it_lock_mode = LCK_PW; - LL_SAVE_INTENT(de, it); - } else { - ldlm_lock_decref(&lockh, LCK_PW); - } - RETURN(1); - } - if (S_ISDIR(de->d_inode->i_mode)) - ll_invalidate_inode_pages(de->d_inode); - d_unhash_aliases(de->d_inode); - RETURN(0); - } - - rc = ll_intent_lock(de->d_parent->d_inode, &de, it, revalidate2_finish); - if (rc < 0) { - CERROR("ll_intent_lock: rc %d : it->it_status %d\n", rc, - it->it_status); - RETURN(0); - } - /* 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); -} - -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 21192aa..0000000 --- a/lustre/llite/dir.c +++ /dev/null @@ -1,827 +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-2003, 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) -{ - CDEBUG(D_VFSTRACE, "VFS Op\n"); - 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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - if ((inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT <= page->index){ - /* XXX why do we need this exactly, and why do we think that - * an all-zero directory page is useful? - */ - CERROR("memsetting dir page %lu to zero (size %lld)\n", - page->index, inode->i_size); - 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 < 0) { - CERROR("lock enqueue: err: %d\n", rc); - unlock_page(page); - RETURN(rc); - } - ldlm_lock_dump_handle(D_OTHER, &lockh); - - 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); - ll_unlock(LCK_PR, &lockh); - if (rc != ELDLM_OK) - CERROR("ll_unlock: err: %d\n", rc); - return rc; -} - -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; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - dir->i_version = ++event; -#endif - 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+%u, 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_dir_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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - 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; - - CDEBUG(D_EXT2, "reading %lu of dir %lu page %lu, size %llu\n", - PAGE_CACHE_SIZE, inode->i_ino, n, inode->i_size); - page = ll_get_dir_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_dir_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_dir_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_dir_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_dir_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; -} - -static int ll_dir_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct obd_ioctl_data *data; - ENTRY; - CDEBUG(D_VFSTRACE, "VFS Op\n"); - - switch(cmd) { - case IOC_MDC_LOOKUP: { - struct ptlrpc_request *request = NULL; - char *buf = NULL; - char *filename; - int namelen, rc, err, len = 0; - int ea_size = 0; // obd_size_wiremd(&sbi->ll_osc_conn, NULL); - unsigned long valid; - - rc = obd_ioctl_getdata(&buf, &len, (void *)arg); - if (rc) - RETURN(rc); - data = (void *)buf; - - filename = data->ioc_inlbuf1; - namelen = data->ioc_inllen1; - - if (namelen < 1) { - CERROR("IOC_MDC_LOOKUP missing filename\n"); - GOTO(out, rc = -EINVAL); - } - - valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE; - rc = mdc_getattr_name(&sbi->ll_mdc_conn, inode, filename, - namelen, valid, ea_size, &request); - if (rc < 0) { - CERROR("mdc_getattr_name: %d\n", rc); - GOTO(out, rc); - } else { - struct mds_body *body; - body = lustre_msg_buf(request->rq_repmsg, 0); - /* surely there's a better way -phik */ - data->ioc_obdo1.o_mode = body->mode; - data->ioc_obdo1.o_uid = body->uid; - data->ioc_obdo1.o_gid = body->gid; - } - - err = copy_to_user((void *)arg, buf, len); - if (err) - GOTO(out_req, rc = -EFAULT); - - EXIT; - out_req: - ptlrpc_req_finished(request); - out: - OBD_FREE(buf, len); - return rc; - } - default: - CERROR("unrecognized ioctl %#x\n", cmd); - RETURN(-ENOTTY); - } -} - -struct file_operations ll_dir_operations = { - read: generic_read_dir, - readdir: ll_readdir, - ioctl: ll_dir_ioctl -}; diff --git a/lustre/llite/file.c b/lustre/llite/file.c deleted file mode 100644 index ff5d1d6..0000000 --- a/lustre/llite/file.c +++ /dev/null @@ -1,914 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * Author: Peter Braam - * Author: Phil Schwan - * 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_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); - -static int ll_mdc_close(struct lustre_handle *mdc_conn, struct inode *inode, - struct file *file) -{ - struct ll_file_data *fd = file->private_data; - struct ptlrpc_request *req = NULL; - unsigned long flags; - struct obd_import *imp; - int rc; - ENTRY; - - /* Complete the open request and remove it from replay list */ - rc = mdc_close(&ll_i2sbi(inode)->ll_mdc_conn, inode->i_ino, - inode->i_mode, &fd->fd_mdshandle, &req); - if (rc) - CERROR("inode %lu close failed: rc = %d\n", inode->i_ino, rc); - - imp = fd->fd_req->rq_import; - LASSERT(imp != NULL); - spin_lock_irqsave(&imp->imp_lock, flags); - - DEBUG_REQ(D_HA, fd->fd_req, "matched open req %p", fd->fd_req); - - /* We held on to the request for replay until we saw a close for that - * file. Now that we've closed it, it gets replayed on the basis of - * its transno only. */ - fd->fd_req->rq_flags &= ~PTL_RPC_FL_REPLAY; - - if (fd->fd_req->rq_transno) { - /* This open created a file, so it needs replay as a - * normal transaction now. Our reference to it now - * effectively owned by the imp_replay_list, and it'll - * be committed just like other transno-having - * requests from here on out. */ - - /* We now retain this close request, so that it is - * replayed if the open is replayed. We duplicate the - * transno, so that we get freed at the right time, - * and rely on the difference in xid to keep - * everything ordered correctly. - * - * But! If this close was already given a transno - * (because it caused real unlinking of an - * open-unlinked file, f.e.), then we'll be ordered on - * the basis of that and we don't need to do anything - * magical here. */ - if (!req->rq_transno) { - req->rq_transno = fd->fd_req->rq_transno; - ptlrpc_retain_replayable_request(req, imp); - } - spin_unlock_irqrestore(&imp->imp_lock, flags); - - /* Should we free_committed now? we always free before - * replay, so it's probably a wash. We could check to - * see if the fd_req should already be committed, in - * which case we can avoid the whole retain_replayable - * dance. */ - } else { - /* No transno means that we can just drop our ref. */ - spin_unlock_irqrestore(&imp->imp_lock, flags); - } - ptlrpc_req_finished(fd->fd_req); - - /* Do this after the fd_req->rq_transno check, because we don't want - * to bounce off zero references. */ - ptlrpc_req_finished(req); - fd->fd_mdshandle.cookie = DEAD_HANDLE_MAGIC; - file->private_data = NULL; - kmem_cache_free(ll_file_data_slab, fd); - - RETURN(-abs(rc)); -} - -/* While this returns an error code, fput() the caller does not, so we need - * to make every effort to clean up all of our state here. Also, applications - * rarely check close errors and even if an error is returned they will not - * re-try the close call. - */ -static int ll_file_release(struct inode *inode, struct file *file) -{ - 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 = 0, rc2; - - ENTRY; - - fd = (struct ll_file_data *)file->private_data; - if (!fd) /* no process opened the file after an mcreate */ - RETURN(rc = 0); - - if (lsm != NULL) { - memset(&oa, 0, sizeof(oa)); - oa.o_id = lsm->lsm_object_id; - oa.o_mode = S_IFREG; - oa.o_valid = OBD_MD_FLTYPE | OBD_MD_FLID; - - memcpy(&oa.o_inline, fd->fd_ostdata, FD_OSTDATA_SIZE); - oa.o_valid |= OBD_MD_FLHANDLE; - - rc = obd_close(&sbi->ll_osc_conn, &oa, lsm, NULL); - if (rc) - CERROR("inode %lu object close failed: rc = %d\n", - inode->i_ino, rc); - } - - rc2 = ll_mdc_close(&sbi->ll_mdc_conn, inode, file); - if (rc2 && !rc) - rc = rc2; - - RETURN(rc); -} - -static int ll_local_open(struct file *file, struct lookup_intent *it) -{ - struct ptlrpc_request *req = it->it_data; - struct ll_file_data *fd; - struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 1); - ENTRY; - - LASSERT(!file->private_data); - - fd = kmem_cache_alloc(ll_file_data_slab, SLAB_KERNEL); - /* We can't handle this well without reorganizing ll_file_open and - * ll_mdc_close, so don't even try right now. */ - LASSERT(fd != NULL); - - memset(fd, 0, sizeof(*fd)); - - memcpy(&fd->fd_mdshandle, &body->handle, sizeof(body->handle)); - fd->fd_req = it->it_data; - file->private_data = fd; - - RETURN(0); -} - -static int ll_osc_open(struct lustre_handle *conn, struct inode *inode, - struct file *file, struct lov_stripe_md *lsm) -{ - struct ll_file_data *fd = file->private_data; - struct obdo *oa; - int rc; - ENTRY; - - oa = obdo_alloc(); - if (!oa) - RETURN(-ENOMEM); - oa->o_id = lsm->lsm_object_id; - oa->o_mode = S_IFREG; - oa->o_valid = (OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE | - OBD_MD_FLBLOCKS | OBD_MD_FLMTIME | OBD_MD_FLCTIME); - rc = obd_open(conn, oa, lsm, NULL); - if (rc) - GOTO(out, rc); - - file->f_flags &= ~O_LOV_DELAY_CREATE; - obdo_to_inode(inode, oa, (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS | - OBD_MD_FLMTIME | OBD_MD_FLCTIME)); - - if (oa->o_valid |= OBD_MD_FLHANDLE) - memcpy(fd->fd_ostdata, obdo_handle(oa), FD_OSTDATA_SIZE); - - EXIT; -out: - obdo_free(oa); - return rc; -} - -/* Caller must hold lli_open_sem to protect lli->lli_smd from changing and - * duplicate objects from being created. We only install lsm to lli_smd if - * the mdc open was successful (hence stored stripe MD on MDS), otherwise - * other nodes could try to create different objects for the same file. - */ -static int ll_create_obj(struct lustre_handle *conn, struct inode *inode, - struct file *file, struct lov_stripe_md *lsm) -{ - struct ptlrpc_request *req = NULL; - struct ll_inode_info *lli = ll_i2info(inode); - struct lov_mds_md *lmm = NULL; - struct obdo *oa; - struct iattr iattr; - int rc, err, lmm_size = 0;; - ENTRY; - - oa = obdo_alloc(); - if (!oa) - RETURN(-ENOMEM); - - oa->o_mode = S_IFREG | 0600; - oa->o_id = inode->i_ino; - /* Keep these 0 for now, because chown/chgrp does not change the - * ownership on the OST, and we don't want to allow BA OST NFS - * users to access these objects by mistake. - */ - oa->o_uid = 0; - oa->o_gid = 0; - oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE | - OBD_MD_FLUID | OBD_MD_FLGID; - - rc = obd_create(conn, oa, &lsm, NULL); - if (rc) { - CERROR("error creating objects for inode %lu: rc = %d\n", - inode->i_ino, rc); - if (rc > 0) { - CERROR("obd_create returned invalid rc %d\n", rc); - rc = -EIO; - } - GOTO(out_oa, rc); - } - - LASSERT(lsm && lsm->lsm_object_id); - rc = obd_packmd(conn, &lmm, lsm); - if (rc < 0) - GOTO(out_destroy, rc); - - lmm_size = rc; - - /* Save the stripe MD with this file on the MDS */ - memset(&iattr, 0, sizeof(iattr)); - iattr.ia_valid = ATTR_FROM_OPEN; - rc = mdc_setattr(&ll_i2sbi(inode)->ll_mdc_conn, inode, &iattr, - lmm, lmm_size, &req); - ptlrpc_req_finished(req); - - obd_free_wiremd(conn, &lmm); - - /* If we couldn't complete mdc_open() and store the stripe MD on the - * MDS, we need to destroy the objects now or they will be leaked. - */ - if (rc) { - CERROR("error: storing stripe MD for %lu: rc %d\n", - inode->i_ino, rc); - GOTO(out_destroy, rc); - } - lli->lli_smd = lsm; - - EXIT; -out_oa: - obdo_free(oa); - return rc; - -out_destroy: - obdo_from_inode(oa, inode, OBD_MD_FLTYPE); - oa->o_id = lsm->lsm_object_id; - oa->o_valid |= OBD_MD_FLID; - err = obd_destroy(conn, oa, lsm, NULL); - obd_free_memmd(conn, &lsm); - if (err) - CERROR("error uncreating inode %lu objects: rc %d\n", - inode->i_ino, err); - goto out_oa; -} - -/* Open a file, and (for the very first open) create objects on the OSTs at - * this time. If opened with O_LOV_DELAY_CREATE, then we don't do the object - * creation or open until ll_lov_setstripe() ioctl is called. We grab - * lli_open_sem to ensure no other process will create objects, send the - * stripe MD to the MDS, or try to destroy the objects if that fails. - * - * If we already have the stripe MD locally then we don't request it in - * mdc_open(), by passing a lmm_size = 0. - * - * It is up to the application to ensure no other processes open this file - * in the O_LOV_DELAY_CREATE case, or the default striping pattern will be - * used. We might be able to avoid races of that sort by getting lli_open_sem - * before returning in the O_LOV_DELAY_CREATE case and dropping it here - * or in ll_file_release(), but I'm not sure that is desirable/necessary. - */ -extern int ll_it_open_error(int phase, struct lookup_intent *it); - -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 lookup_intent *it; - struct lov_stripe_md *lsm; - int rc = 0; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - LL_GET_INTENT(file->f_dentry, it); - rc = ll_it_open_error(IT_OPEN_OPEN, it); - if (rc) - RETURN(rc); - - rc = ll_local_open(file, it); - if (rc) - LBUG(); - - mdc_set_open_replay_data((struct ll_file_data *)file->private_data); - - lsm = lli->lli_smd; - 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); - if (!lli->lli_smd) { - rc = ll_create_obj(conn, inode, file, NULL); - up(&lli->lli_open_sem); - if (rc) - GOTO(out_close, rc); - } else { - CERROR("warning: stripe already set on ino %lu\n", - inode->i_ino); - up(&lli->lli_open_sem); - } - lsm = lli->lli_smd; - } - - rc = ll_osc_open(conn, inode, file, lsm); - if (rc) - GOTO(out_close, rc); - RETURN(0); - - out_close: - ll_mdc_close(&sbi->ll_mdc_conn, inode, file); - return rc; -} - -int ll_size_lock(struct inode *inode, struct lov_stripe_md *lsm, obd_off start, - int mode, struct lustre_handle *lockh) -{ - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct ldlm_extent extent; - int rc, flags = 0; - ENTRY; - - /* XXX phil: can we do this? won't it screw the file size up? */ - if (sbi->ll_flags & LL_SBI_NOLCK) - RETURN(0); - - 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), lockh); - RETURN(rc); -} - -int ll_size_unlock(struct inode *inode, struct lov_stripe_md *lsm, int mode, - struct lustre_handle *lockh) -{ - struct ll_sb_info *sbi = ll_i2sbi(inode); - int rc; - ENTRY; - - /* XXX phil: can we do this? won't it screw the file size up? */ - if (sbi->ll_flags & LL_SBI_NOLCK) - RETURN(0); - - rc = obd_cancel(&sbi->ll_osc_conn, lsm, mode, lockh); - if (rc != ELDLM_OK) { - CERROR("lock cancel: %d\n", rc); - LBUG(); - } - - RETURN(rc); -} - -/* This function is solely "sampling" the file size, and does not explicit - * locking on the size itself (see ll_size_lock() and ll_size_unlock()). - * - * XXX We need to optimize away the obd_getattr for decent performance here, - * by checking if we already have the size lock and considering our size - * authoritative in that case. In order to do that either the act of - * getting the size lock includes retrieving the file size, or the client - * keeps an atomic flag in the inode which indicates whether the size - * has been updated (see bug 280). - */ -int ll_file_size(struct inode *inode, struct lov_stripe_md *lsm, char *ostdata) -{ - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct obdo oa; - int rc; - ENTRY; - - LASSERT(lsm); - LASSERT(sbi); - - memset(&oa, 0, sizeof oa); - oa.o_id = lsm->lsm_object_id; - oa.o_mode = S_IFREG; - oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE | - OBD_MD_FLBLOCKS | OBD_MD_FLMTIME | OBD_MD_FLCTIME; - - if (ostdata != NULL) { - memcpy(&oa.o_inline, ostdata, FD_OSTDATA_SIZE); - oa.o_valid |= OBD_MD_FLHANDLE; - } - - rc = obd_getattr(&sbi->ll_osc_conn, &oa, lsm); - if (!rc) { - obdo_to_inode(inode, &oa, OBD_MD_FLSIZE | OBD_MD_FLBLOCKS | - OBD_MD_FLMTIME | OBD_MD_FLCTIME); - CDEBUG(D_INODE, "objid "LPX64" size %Lu/%Lx\n", - lsm->lsm_object_id, inode->i_size, inode->i_size); - } - - 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) -{ -#ifdef USE_ATIME - struct iattr attr; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - attr.ia_atime = CURRENT_TIME; -#else - attr.ia_atime = CURRENT_TIME.tv_sec; -#endif - 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); -#else - /* update atime, but don't explicitly write it out just this change */ - inode->i_atime = CURRENT_TIME; -#endif -} - -int ll_lock_callback(struct ldlm_lock *lock, struct ldlm_lock_desc *new, - void *data, int flag) -{ - struct inode *inode = data; - struct lustre_handle lockh = { 0, 0 }; - int rc; - ENTRY; - CDEBUG(D_VFSTRACE, "VFS Op\n"); - - 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 %lu\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 = filp->private_data; - struct inode *inode = filp->f_dentry->d_inode; - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct lustre_handle lockh = { 0, 0 }; - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - int flags = 0; - ldlm_error_t err; - ssize_t retval; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK) && - !(sbi->ll_flags & LL_SBI_NOLCK)) { - struct ldlm_extent extent; - extent.start = *ppos; - extent.end = *ppos + count - 1; - CDEBUG(D_INFO, "Locking inode %lu, 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), - &lockh); - if (err != ELDLM_OK) { - CERROR("lock enqueue: err: %d\n", err); - RETURN(err); - } - } - - /* If we don't refresh the file size, generic_file_read may not even - * call ll_readpage */ - retval = ll_file_size(inode, lsm, fd->fd_ostdata); - if (retval < 0) { - CERROR("ll_file_size: "LPSZ"\n", retval); - RETURN(retval); - } - - CDEBUG(D_INFO, "Reading inode %lu, "LPSZ" 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, &lockh); - if (err != ELDLM_OK) { - CERROR("lock cancel: err: %d\n", err); - retval = err; - } - } - - 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 = file->private_data; - struct inode *inode = file->f_dentry->d_inode; - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct lustre_handle lockh = { 0, 0 }, eof_lockh = { 0, 0 }; - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - int flags = 0; - ldlm_error_t err; - ssize_t retval; - ENTRY; - - /* POSIX, but surprised the VFS doesn't check this already */ - if (count == 0) - return 0; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - if (!S_ISBLK(inode->i_mode) && file->f_flags & O_APPEND) { - err = ll_size_lock(inode, lsm, 0, LCK_PW, &eof_lockh); - if (err) - RETURN(err); - - /* Get size here so we know extent to enqueue write lock on. */ - retval = ll_file_size(inode, lsm, fd->fd_ostdata); - if (retval) - GOTO(out_eof, retval); - - *ppos = inode->i_size; - } - - if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK) && - !(sbi->ll_flags & LL_SBI_NOLCK)) { - struct ldlm_extent extent; - extent.start = *ppos; - extent.end = *ppos + count - 1; - CDEBUG(D_INFO, "Locking inode %lu, 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), - &lockh); - if (err != ELDLM_OK) { - CERROR("lock enqueue: err: %d\n", err); - GOTO(out_eof, retval = err); - } - } - - CDEBUG(D_INFO, "Writing inode %lu, "LPSZ" bytes, offset %Lu\n", - inode->i_ino, 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, &lockh); - if (err != ELDLM_OK) - CERROR("lock cancel: err: %d\n", err); - } - - EXIT; - out_eof: - if (!S_ISBLK(inode->i_mode) && file->f_flags & O_APPEND) { - err = ll_size_unlock(inode, lsm, LCK_PW, &eof_lockh); - if (err) - CERROR("ll_size_unlock: %d\n", err); - } - - return retval; -} - -static int ll_lov_setstripe(struct inode *inode, struct file *file, - unsigned long arg) -{ - struct ll_inode_info *lli = ll_i2info(inode); - struct lustre_handle *conn = ll_i2obdconn(inode); - struct lov_stripe_md *lsm; - int rc; - ENTRY; - - down(&lli->lli_open_sem); - lsm = lli->lli_smd; - if (lsm) { - up(&lli->lli_open_sem); - CERROR("stripe already set for ino %lu\n", inode->i_ino); - /* If we haven't already done the open, do so now */ - if (file->f_flags & O_LOV_DELAY_CREATE) { - int rc2 = ll_osc_open(conn, inode, file, lsm); - if (rc2) - RETURN(rc2); - } - - RETURN(-EALREADY); - } - - rc = obd_iocontrol(LL_IOC_LOV_SETSTRIPE, conn, 0, &lsm, (void *)arg); - if (rc) { - up(&lli->lli_open_sem); - RETURN(rc); - } - rc = ll_create_obj(conn, inode, file, lsm); - up(&lli->lli_open_sem); - - if (rc) { - obd_free_memmd(conn, &lsm); - RETURN(rc); - } - rc = ll_osc_open(conn, inode, file, lli->lli_smd); - RETURN(rc); -} - -static int ll_lov_getstripe(struct inode *inode, unsigned long arg) -{ - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - struct lustre_handle *conn = ll_i2obdconn(inode); - - if (!lsm) - RETURN(-ENODATA); - - return obd_iocontrol(LL_IOC_LOV_GETSTRIPE, conn, 0, lsm, (void *)arg); -} - -int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct ll_file_data *fd = file->private_data; - struct lustre_handle *conn; - int flags; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - - if ((cmd & 0xffffff00) == ((int)'T') << 8) /* tty ioctls */ - return -ENOTTY; - - 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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - switch (origin) { - case 2: { - struct ll_inode_info *lli = ll_i2info(inode); - struct ll_file_data *fd = file->private_data; - - retval = ll_file_size(inode, lli->lli_smd, fd->fd_ostdata); - 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; - file->f_version = ++event; -#endif - } - 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; -} - -int ll_inode_revalidate(struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - struct lov_stripe_md *lsm; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - if (!inode) { - CERROR("REPORT THIS LINE TO PETER\n"); - RETURN(0); - } - - /* this is very tricky. it is unsafe to call ll_have_md_lock - when we have a referenced lock: because it may cause an RPC - below when the lock is marked CB_PENDING. That RPC may not - go out because someone else may be in another RPC waiting for - that lock*/ - if (!(dentry->d_it && dentry->d_it->it_lock_mode) && - !ll_have_md_lock(dentry)) { - struct ptlrpc_request *req = NULL; - struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode); - struct mds_body *body; - unsigned long valid = 0; - int datalen = 0, rc; - - /* Why don't we update all valid MDS fields here, if we're - * doing an RPC anyways? -phil */ - if (S_ISREG(inode->i_mode)) { - datalen = obd_size_wiremd(&sbi->ll_osc_conn, NULL); - valid |= OBD_MD_FLEASIZE; - } - rc = mdc_getattr(&sbi->ll_mdc_conn, inode->i_ino, - inode->i_mode, valid, datalen, &req); - if (rc) { - CERROR("failure %d inode %lu\n", rc, inode->i_ino); - ptlrpc_req_finished(req); - RETURN(-abs(rc)); - } - - body = lustre_msg_buf(req->rq_repmsg, 0); - - if (S_ISREG(inode->i_mode) && - body->valid & (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) { - CERROR("MDS sent back size for regular file\n"); - body->valid &= ~(OBD_MD_FLSIZE | OBD_MD_FLBLOCKS); - } - - if (body->valid & OBD_MD_FLEASIZE) - ll_update_inode(inode, body, - lustre_msg_buf(req->rq_repmsg, 1)); - else - ll_update_inode(inode, body, NULL); - ptlrpc_req_finished(req); - } - - lsm = ll_i2info(inode)->lli_smd; - if (!lsm) /* object not yet allocated, don't validate size */ - RETURN(0); - - /* XXX this should probably become an unconditional obd_getattr() - * so that we update the blocks count and mtime from the OST too. - */ - RETURN(ll_file_size(inode, lsm, NULL)); -} - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int ll_getattr(struct vfsmount *mnt, struct dentry *de, - struct kstat *stat) -{ - int res = 0; - struct inode *inode = de->d_inode; - - res = ll_inode_revalidate(de); - if (res) - return res; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - stat->dev = inode->i_dev; -#endif - stat->ino = inode->i_ino; - stat->mode = inode->i_mode; - stat->nlink = inode->i_nlink; - stat->uid = inode->i_uid; - stat->gid = inode->i_gid; - stat->rdev = kdev_t_to_nr(inode->i_rdev); - stat->atime = inode->i_atime; - stat->mtime = inode->i_mtime; - stat->ctime = inode->i_ctime; - stat->size = inode->i_size; - return 0; -} -#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_raw: ll_setattr_raw, - setattr: ll_setattr, - truncate: ll_truncate, -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - getattr: ll_getattr, -#else - revalidate: ll_inode_revalidate, -#endif -}; - -struct inode_operations ll_special_inode_operations = { - setattr_raw: ll_setattr_raw, - setattr: ll_setattr, -#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 b5e6620..0000000 --- a/lustre/llite/lproc_llite.c +++ /dev/null @@ -1,182 +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 -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#endif -#include -#include - -/* /proc/lustre/llite mount point registration */ - -#ifndef LPROCFS -int lprocfs_register_mountpoint(struct proc_dir_entry *parent, - struct super_block *sb, char *osc, char *mdc) -{ - return 0; -} -#else - -#define LPROC_LLITE_STAT_FCT(fct_name, get_statfs_fct) \ -int fct_name(char *page, char **start, off_t off, \ - int count, int *eof, void *data) \ -{ \ - struct statfs sfs; \ - int rc; \ - LASSERT(data != NULL); \ - rc = get_statfs_fct((struct super_block*)data, &sfs); \ - return (rc==0 \ - ? lprocfs_##fct_name (page, start, off, count, eof, &sfs) \ - : rc); \ -} - -long long mnt_instance; - -LPROC_LLITE_STAT_FCT(rd_blksize, vfs_statfs); -LPROC_LLITE_STAT_FCT(rd_kbytestotal, vfs_statfs); -LPROC_LLITE_STAT_FCT(rd_kbytesfree, vfs_statfs); -LPROC_LLITE_STAT_FCT(rd_filestotal, vfs_statfs); -LPROC_LLITE_STAT_FCT(rd_filesfree, vfs_statfs); -LPROC_LLITE_STAT_FCT(rd_filegroups, vfs_statfs); - -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) -{ - struct super_block *sb = (struct super_block*)data; - - LASSERT(sb != NULL); - *eof = 1; - return snprintf(page, count, "%s\n", sb->s_type->name); -} - -int rd_sb_uuid(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - struct super_block *sb = (struct super_block *)data; - - LASSERT(sb != NULL); - *eof = 1; - return snprintf(page, count, "%s\n", ll_s2sbi(sb)->ll_sb_uuid.uuid); -} - -struct lprocfs_vars lprocfs_obd_vars[] = { - { "uuid", rd_sb_uuid, 0, 0 }, - { "mntpt_path", rd_path, 0, 0 }, - { "fstype", rd_fstype, 0, 0 }, - { "blocksize", rd_blksize, 0, 0 }, - { "kbytestotal", rd_kbytestotal, 0, 0 }, - { "kbytesfree", rd_kbytesfree, 0, 0 }, - { "filestotal", rd_filestotal, 0, 0 }, - { "filesfree", rd_filesfree, 0, 0 }, - { "filegroups", rd_filegroups, 0, 0 }, - { 0 } -}; - -#define MAX_STRING_SIZE 128 -int lprocfs_register_mountpoint(struct proc_dir_entry *parent, - struct super_block *sb, char *osc, char *mdc) -{ - struct lprocfs_vars lvars[2]; - struct ll_sb_info *sbi = ll_s2sbi(sb); - struct obd_device *obd; - char name[MAX_STRING_SIZE + 1]; - struct obd_uuid uuid; - int err; - ENTRY; - - memset(lvars, 0, sizeof(lvars)); - - name[MAX_STRING_SIZE] = '\0'; - lvars[0].name = name; - - LASSERT(sbi != NULL); - LASSERT(mdc != NULL); - LASSERT(osc != NULL); - - /* Mount info */ - snprintf(name, MAX_STRING_SIZE, "fs%llu", mnt_instance); - - mnt_instance++; - sbi->ll_proc_root = lprocfs_register(name, parent, NULL, NULL); - if (IS_ERR(sbi->ll_proc_root)) { - err = PTR_ERR(sbi->ll_proc_root); - sbi->ll_proc_root = NULL; - RETURN(err); - } - /* Static configuration info */ - err = lprocfs_add_vars(sbi->ll_proc_root, lprocfs_obd_vars, sb); - if (err) - RETURN(err); - - /* MDC info */ - strncpy(uuid.uuid, mdc, sizeof(uuid.uuid)); - obd = class_uuid2obd(&uuid); - - LASSERT(obd != NULL); - LASSERT(obd->obd_type != NULL); - LASSERT(obd->obd_type->typ_name != NULL); - - snprintf(name, MAX_STRING_SIZE, "%s/common_name", - obd->obd_type->typ_name); - lvars[0].read_fptr = lprocfs_rd_name; - err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd); - if (err) - RETURN(err); - - snprintf(name, MAX_STRING_SIZE, "%s/uuid", obd->obd_type->typ_name); - lvars[0].read_fptr = lprocfs_rd_uuid; - err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd); - if (err < 0) - RETURN(err); - - /* OSC */ - strncpy(uuid.uuid, osc, sizeof(uuid.uuid)); - obd = class_uuid2obd(&uuid); - - LASSERT(obd != NULL); - LASSERT(obd->obd_type != NULL); - LASSERT(obd->obd_type->typ_name != NULL); - - snprintf(name, MAX_STRING_SIZE, "%s/common_name", - obd->obd_type->typ_name); - lvars[0].read_fptr = lprocfs_rd_name; - err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd); - if (err) - RETURN(err); - - snprintf(name, MAX_STRING_SIZE, "%s/uuid", obd->obd_type->typ_name); - lvars[0].read_fptr = lprocfs_rd_uuid; - err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd); - - RETURN(err); -} - -#undef MAX_STRING_SIZE -#endif /* LPROCFS */ diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c deleted file mode 100644 index 449cac7..0000000 --- a/lustre/llite/namei.c +++ /dev/null @@ -1,1201 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * derived in small part 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 - */ - -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include -#include - -/* from dcache.c */ -extern void ll_set_dd(struct dentry *de); - -/* 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, lic->lic_lmm); - - 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) - return LCK_PW; - else if (it->it_op & (IT_READDIR | IT_GETATTR | IT_OPEN | IT_LOOKUP)) - return LCK_PR; - - LBUG(); - RETURN(-EINVAL); -} - -int ll_it_open_error(int phase, struct lookup_intent *it) -{ - if (it->it_disposition & IT_OPEN_OPEN) { - if (phase == IT_OPEN_OPEN) - return it->it_status; - else - return 0; - } - - if (it->it_disposition & IT_OPEN_CREATE) { - if (phase == IT_OPEN_CREATE) - return it->it_status; - else - return 0; - } - - if (it->it_disposition & IT_OPEN_LOOKUP) { - if (phase == IT_OPEN_LOOKUP) - return it->it_status; - else - return 0; - } - LBUG(); - return 0; -} - -#define IT_ENQ_COMPLETE (1<<16) - -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 = 0, datalen = 0, offset, flag = 0; - obd_id ino = 0; - ENTRY; - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - if (it && it->it_op == 0) - *it = lookup_it; -#endif - 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); - - if (!(it->it_disposition & IT_ENQ_COMPLETE)) { - rc = mdc_enqueue(&sbi->ll_mdc_conn, LDLM_PLAIN, it, - ll_intent_to_lock_mode(it), 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; - - /* non-zero it_disposition indicates that the server performed the - * intent on our behalf. */ - if (it->it_disposition) { - struct mds_body *mds_body; - int mode; - - /* 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; - - /*We were called from revalidate2: did we find the same inode?*/ - if ((*de)->d_inode && - (ino != (*de)->d_inode->i_ino || - mds_body->fid1.generation != (*de)->d_inode->i_generation)) { - it->it_disposition |= IT_ENQ_COMPLETE; - RETURN(-ESTALE); - } - - /* If we're doing an IT_OPEN which did not result in an actual - * successful open, then we need to remove the bit which saves - * this request for unconditional replay. */ - if (it->it_op & IT_OPEN && - (!(it->it_disposition & IT_OPEN_OPEN) || - it->it_status != 0)) - request->rq_flags &= ~PTL_RPC_FL_REPLAY; - - if (it->it_op & IT_CREAT) { - mdc_store_inode_generation(request, 2, 1); - /* The server will return to us, in it_disposition, an - * indication of exactly what it_status refers to. - * - * If IT_OPEN_OPEN is set, then it_status refers to the - * open() call, otherwise if IT_OPEN_CREATE is set, then - * it status is the creation failure mode. In either - * case, one of IT_OPEN_NEG or IT_OPEN_POS will be set, - * indicating whether the child lookup was successful. - * - * Else, if IT_OPEN_LOOKUP then it_status is the rc - * of the child lookup. - * - * Finally, if none of the bits are set, then the - * failure occurred while looking up the parent. */ - rc = ll_it_open_error(IT_OPEN_LOOKUP, it); - if (rc) - GOTO(drop_req, rc); - - if (it->it_disposition & IT_OPEN_CREATE) - ptlrpc_request_addref(request); - if (it->it_disposition & IT_OPEN_OPEN) - ptlrpc_request_addref(request); - - if (it->it_disposition & IT_OPEN_NEG) - flag = LL_LOOKUP_NEGATIVE; - else - flag = LL_LOOKUP_POSITIVE; - } else if (it->it_op == IT_OPEN) { - LASSERT(!(it->it_disposition & IT_OPEN_CREATE)); - - rc = ll_it_open_error(IT_OPEN_LOOKUP, it); - if (rc) - GOTO(drop_req, rc); - - if (it->it_disposition & IT_OPEN_OPEN) - ptlrpc_request_addref(request); - - if (it->it_disposition & IT_OPEN_NEG) - flag = LL_LOOKUP_NEGATIVE; - else - flag = LL_LOOKUP_POSITIVE; - } else if (it->it_op & (IT_GETATTR | IT_LOOKUP)) { - /* For check ops, we want the lookup to succeed */ - it->it_data = NULL; - if (it->it_status) - flag = LL_LOOKUP_NEGATIVE; - else - flag = LL_LOOKUP_POSITIVE; - } else - LBUG(); - } 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; - } else { - valid |= OBD_MD_FLBLOCKS; - } - - 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)); - } - } - - 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); - } - - /* 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... (we need to save it in the GETATTR case for the - * benefit of ll_inode_revalidate -phil) */ - if (it->it_op & (IT_OPEN | IT_GETATTR)) - 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 (it->it_op == IT_LOOKUP) - ll_intent_release(dentry, it); - - RETURN(rc); - - drop_req: - ptlrpc_req_finished(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); - __d_rehash(dentry, 0); /* avoid taking dcache_lock inside */ - spin_unlock(&dcache_lock); - atomic_inc(&dentry->d_count); - iput(inode); - dentry->d_flags &= ~DCACHE_LUSTRE_INVALID; - 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_NEGATIVE)) { - 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. */ - mdc_lock_set_inode((struct lustre_handle *)it->it_lock_handle, - inode); - } else { - ENTRY; - } - - ptlrpc_req_finished(request); - - dentry->d_op = &ll_d_ops; - 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; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - rc = ll_intent_lock(parent, &dentry, it, lookup2_finish); - if (rc < 0) { - CDEBUG(D_INFO, "ll_intent_lock: %d\n", rc); - RETURN(ERR_PTR(rc)); - } - - if (dentry == save) - RETURN(NULL); - else - RETURN(dentry); -} - -/* We depend on "mode" being set with the proper file type/umask by now */ -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; -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - time_t time = CURRENT_TIME.tv_sec; -#else - time_t time = CURRENT_TIME; -#endif - struct ll_sb_info *sbi = ll_i2sbi(dir); - struct ll_read_inode2_cookie lic = { .lic_lmm = NULL, }; - ENTRY; - - if (it && it->it_disposition) { - 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. */ - mdc_lock_set_inode((struct lustre_handle *)it->it_lock_handle, - 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); - struct mds_body *body; - struct lov_stripe_md *lsm = NULL; - struct lustre_handle lockh; - struct lookup_intent it = { .it_op = IT_UNLINK }; - struct obdo *oa; - int err; - struct mdc_unlink_data data; - ENTRY; - - data.unl_dir = dir; - data.unl_de = child; - data.unl_mode = mode; - data.unl_name = name; - data.unl_len = len; - - err = mdc_enqueue(&sbi->ll_mdc_conn, LDLM_PLAIN, &it, LCK_EX, dir, - NULL, &lockh, NULL, 0, &data, sizeof(data)); - request = (struct ptlrpc_request *)it.it_data; - if (err < 0) - GOTO(out, err); - if (it.it_status) - GOTO(out, err = it.it_status); - err = 0; - - body = lustre_msg_buf(request->rq_repmsg, 1); - LASSERT(body != NULL); - if (!(body->valid & OBD_MD_FLEASIZE)) - GOTO(out, 0); - - /* The MDS sent back the EA because we unlinked the last reference - * to this file. Use this EA to unlink the objects on the OST */ - err = obd_unpackmd(ll_i2obdconn(dir), &lsm, - lustre_msg_buf(request->rq_repmsg, 2)); - if (err < 0) - CERROR("obd_unpackmd: %d\n", err); - - oa = obdo_alloc(); - if (oa == NULL) - GOTO(out_unlock, err = -ENOMEM); - - oa->o_id = lsm->lsm_object_id; - oa->o_mode = body->mode & S_IFMT; - oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE; - - err = obd_destroy(ll_i2obdconn(dir), oa, lsm, NULL); - obdo_free(oa); - if (err) - CERROR("obd destroy objid 0x"LPX64" error %d\n", - lsm->lsm_object_id, err); - - obd_free_memmd(ll_i2obdconn(dir), &lsm); - out_unlock: - ldlm_lock_decref_and_cancel(&lockh, LCK_EX); - out: - 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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - it = dentry->d_it; - - rc = ll_it_open_error(IT_OPEN_CREATE, it); - if (rc) { - LL_GET_INTENT(dentry, it); - ptlrpc_req_finished(it->it_data); - RETURN(rc); - } - - inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len, - NULL, 0, mode, 0, it); - - if (IS_ERR(inode)) { - LL_GET_INTENT(dentry, it); - RETURN(PTR_ERR(inode)); - } - - /* no directory data updates when intents rule */ - if (it && it->it_disposition) { - d_instantiate(dentry, inode); - RETURN(0); - } - - rc = ext2_add_nondir(dentry, inode); - RETURN(rc); -} - -static int ll_mknod2(struct inode *dir, const char *name, int len, int mode, - int rdev) -{ - struct ptlrpc_request *request = NULL; -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - time_t time = CURRENT_TIME.tv_sec; -#else - time_t time = CURRENT_TIME; -#endif - struct ll_sb_info *sbi = ll_i2sbi(dir); - int err = -EMLINK; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - if (dir->i_nlink >= EXT2_LINK_MAX) - RETURN(err); - - mode &= ~current->fs->umask; - - switch (mode & S_IFMT) { - case 0: case S_IFREG: - mode |= S_IFREG; /* for mode = 0 case, fallthrough */ - case S_IFCHR: case S_IFBLK: - case S_IFIFO: case S_IFSOCK: - err = mdc_create(&sbi->ll_mdc_conn, dir, name, len, NULL, 0, - mode, current->fsuid, current->fsgid, time, - rdev, &request); - ptlrpc_req_finished(request); - break; - case S_IFDIR: - err = -EPERM; - break; - default: - err = -EINVAL; - } - RETURN(err); -} - -static int ll_mknod(struct inode *dir, struct dentry *dentry, int mode, - int rdev) -{ - struct lookup_intent *it; - struct inode *inode; - int rc = 0; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - LL_GET_INTENT(dentry, it); - - if ((mode & S_IFMT) == 0) - mode |= S_IFREG; - 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_symlink2(struct inode *dir, const char *name, int len, - const char *tgt) -{ - struct ptlrpc_request *request = NULL; -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - time_t time = CURRENT_TIME.tv_sec; -#else - time_t time = CURRENT_TIME; -#endif - struct ll_sb_info *sbi = ll_i2sbi(dir); - int err = -EMLINK; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - if (dir->i_nlink >= EXT2_LINK_MAX) - RETURN(err); - - err = mdc_create(&sbi->ll_mdc_conn, dir, name, len, - tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO, - current->fsuid, current->fsgid, time, 0, &request); - ptlrpc_req_finished(request); - RETURN(err); -} - -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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - 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_link2(struct inode *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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - err = mdc_link(&sbi->ll_mdc_conn, src, dir, name, len, &request); - ptlrpc_req_finished(request); - - 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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - LL_GET_INTENT(dentry, it); - - if (it && it->it_disposition) { - if (it->it_status) - RETURN(it->it_status); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - inode->i_ctime.tv_sec = CURRENT_TIME.tv_sec; -#else - inode->i_ctime = CURRENT_TIME; -#endif - 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_link2(old_dentry->d_inode, dir, - dentry->d_name.name, dentry->d_name.len); - if (rc) - RETURN(rc); - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - inode->i_ctime.tv_sec = CURRENT_TIME.tv_sec; -#else - inode->i_ctime = CURRENT_TIME; -#endif - ext2_inc_count(inode); - atomic_inc(&inode->i_count); - - return ext2_add_nondir(dentry, inode); -} - -static int ll_mkdir2(struct inode *dir, const char *name, int len, int mode) -{ - struct ptlrpc_request *request = NULL; -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - time_t time = CURRENT_TIME.tv_sec; -#else - time_t time = CURRENT_TIME; -#endif - struct ll_sb_info *sbi = ll_i2sbi(dir); - int err = -EMLINK; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - if (dir->i_nlink >= EXT2_LINK_MAX) - RETURN(err); - - mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR; - err = mdc_create(&sbi->ll_mdc_conn, dir, name, len, NULL, 0, - mode, current->fsuid, current->fsgid, - time, 0, &request); - ptlrpc_req_finished(request); - RETURN(err); -} - - -static int ll_mkdir(struct inode *dir, struct dentry *dentry, int mode) -{ - struct lookup_intent *it; - struct inode * inode; - int err = -EMLINK; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - 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_rmdir2(struct inode *dir, const char *name, int len) -{ - int rc; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - rc = ll_mdc_unlink(dir, NULL, S_IFDIR, name, len); - RETURN(rc); -} - -static int ll_unlink2(struct inode *dir, const char *name, int len) -{ - int rc; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - rc = ll_mdc_unlink(dir, NULL, S_IFREG, name, len); - RETURN(rc); -} - -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; - ENTRY; - - 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; - EXIT; -out_dec: - ext2_dec_count(inode); -out: - return rc; -} - -static int ll_unlink(struct inode *dir, struct dentry *dentry) -{ - struct lookup_intent * it; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - 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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - 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_rename2(struct inode *src, struct inode *tgt, - const char *oldname, int oldlen, - const char *newname, int newlen) -{ - struct ptlrpc_request *request = NULL; - struct ll_sb_info *sbi = ll_i2sbi(src); - int err; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - err = mdc_rename(&sbi->ll_mdc_conn, src, tgt, - oldname, oldlen, newname, newlen, &request); - ptlrpc_req_finished(request); - - RETURN(err); -} - - - -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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - LL_GET_INTENT(new_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_rename2(old_dir, new_dir, - old_dentry->d_name.name, old_dentry->d_name.len, - new_dentry->d_name.name, new_dentry->d_name.len); - 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; -} - -extern int ll_inode_revalidate(struct dentry *dentry); -struct inode_operations ll_dir_inode_operations = { - create: ll_create, - lookup2: ll_lookup2, - link: ll_link, - link2: ll_link2, - unlink: ll_unlink, - unlink2: ll_unlink2, - symlink: ll_symlink, - symlink2: ll_symlink2, - mkdir: ll_mkdir, - mkdir2: ll_mkdir2, - rmdir: ll_rmdir, - rmdir2: ll_rmdir2, - mknod: ll_mknod, - mknod2: ll_mknod2, - rename: ll_rename, - rename2: ll_rename2, - setattr: ll_setattr, - setattr_raw: ll_setattr_raw, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - revalidate: ll_inode_revalidate, -#endif -}; diff --git a/lustre/llite/recover.c b/lustre/llite/recover.c deleted file mode 100644 index 4c7ad42..0000000 --- a/lustre/llite/recover.c +++ /dev/null @@ -1,56 +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) { - unsigned long flags; - spin_lock_irqsave(&imp->imp_lock, flags); - imp->imp_level = LUSTRE_CONN_RECOVD; - spin_unlock_irqrestore(&imp->imp_lock, flags); - } - 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 6818ace..0000000 --- a/lustre/llite/rw.c +++ /dev/null @@ -1,505 +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-2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -#include -#else -#include -#endif -#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; - - CDEBUG(D_PAGE, "%s %d bytes ino %lu at "LPU64"/"LPX64"\n", - cmd & OBD_BRW_WRITE ? "write" : "read", pg.count, inode->i_ino, - pg.off, pg.off); - if (pg.count == 0) { - CERROR("ZERO COUNT: ino %lu: size %p:%Lu(%p:%Lu) idx %lu off " - LPU64"\n", - inode->i_ino, inode, inode->i_size, page->mapping->host, - page->mapping->host->i_size, page->index, pg.off); - } - - 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, NULL); - if (rc) { - if (rc != -EIO) - CERROR("error from obd_brw: rc = %d\n", rc); - } else { - rc = ll_brw_sync_wait(set, CB_PHASE_START); - if (rc) - CERROR("error from callback: rc = %d\n", rc); - } - obd_brw_set_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) { - CERROR("reading beyond EOF\n"); - memset(kmap(page), 0, PAGE_SIZE); - kunmap(page); - GOTO(readpage_out, rc); - } - - /* XXX Workaround for BA OSTs returning short reads at EOF. The linux - * OST will return the full page, zero-filled at the end, which - * will just overwrite the data we set here. - * Bug 593 relates to fixing this properly. - */ - if (inode->i_size < offset + PAGE_SIZE) { - int count = inode->i_size - offset; - void *addr = kmap(page); - //POISON(addr, 0x7c, count); - memset(addr + count, 0, PAGE_SIZE - count); - kunmap(page); - } - - if (PageUptodate(page)) { - CERROR("Explain this please?\n"); - GOTO(readpage_out, rc); - } - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - 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 lockh = { 0, 0 }; - 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_VFSTRACE, "VFS Op\n"); - CDEBUG(D_INFO, "calling punch for "LPX64" (all bytes after %Lu)\n", - oa.o_id, inode->i_size); - - err = ll_size_lock(inode, lsm, inode->i_size, LCK_PW, &lockh); - if (err) { - CERROR("ll_size_lock failed: %d\n", err); - return; - } - - /* truncate == punch from new size to absolute end of file */ - err = obd_punch(ll_i2obdconn(inode), &oa, lsm, inode->i_size, - OBD_OBJECT_EOF, NULL); - if (err) - CERROR("obd_truncate fails (%d) ino %lu\n", err, inode->i_ino); - else - obdo_to_inode(inode, &oa, oa.o_valid); - - err = ll_size_unlock(inode, lsm, LCK_PW, &lockh); - 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); - LASSERT(PageLocked(page)); - - if (PageUptodate(page)) - RETURN(0); - - //POISON(addr + from, 0xca, to - from); - - /* 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); - CDEBUG(D_VFSTRACE, "VFS Op\n"); - - /* If are writing to a new page, no need to read old data. If we - * haven't already gotten the file size in ll_file_write() since - * we got our extent lock, we need to verify it here before we - * overwrite some other node's write (bug 445). - */ - if (inode->i_size <= offset) { - if (!S_ISBLK(inode->i_mode) && !(file->f_flags & O_APPEND)) { - struct ll_file_data *fd = file->private_data; - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - - rc = ll_file_size(inode, lsm, fd->fd_ostdata); - if (rc) - GOTO(prepare_done, rc); - } - 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); - else - kunmap (page); - - return rc; -} - -/* Write a page from kupdated or kswapd. - * - * We unlock the page even in the face of an error, otherwise dirty - * pages could OOM the system if they cannot be written. Also, there - * is nobody to return an error code to from here - the application - * may not even be running anymore. - * - * Returns the page unlocked, but with a reference. - */ -static int ll_writepage(struct page *page) { - struct inode *inode = page->mapping->host; - int err; - ENTRY; - - LASSERT(PageLocked(page)); - - /* XXX need to make sure we have LDLM lock on this page */ - CDEBUG(D_VFSTRACE, "VFS Op\n"); - err = ll_brw(OBD_BRW_WRITE, inode, page, 1); - if (err) - CERROR("ll_brw failure %d\n", err); - else - set_page_clean(page); - - 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; - /* XXX make the starting offset "from" */ - 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_VFSTRACE, "VFS Op\n"); - CDEBUG(D_INODE, "commit_page writing (off "LPD64"), count %d\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, NULL); - if (rc) - CERROR("error from obd_brw: rc = %d\n", rc); - else { - rc = ll_brw_sync_wait(set, CB_PHASE_START); - if (rc) - CERROR("error from callback: rc = %d\n", rc); - } - obd_brw_set_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 */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -static int ll_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf, - unsigned long blocknr, int blocksize) -{ - 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; - loff_t offset; - int length, i, flags, rc = 0; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - if (!lsm || !lsm->lsm_object_id) - RETURN(-ENOMEM); - - /* XXX Keep here until we find ia64 problem, it crashes otherwise */ - 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) * iobuf->nr_pages); - if (!pga) { - obd_brw_set_free(set); - RETURN(-ENOMEM); - } - - CDEBUG(D_PAGE, "blocksize %u, blocknr %lu, iobuf %p: nr_pages %u, " - "array_len %u, offset %u, length %u\n", - blocksize, blocknr, iobuf, iobuf->nr_pages, - iobuf->array_len, iobuf->offset, iobuf->length); - - flags = (rw == WRITE ? OBD_BRW_CREATE : 0) /* | OBD_BRW_DIRECTIO */; - offset = (blocknr << inode->i_blkbits) /* + iobuf->offset? */; - length = iobuf->length; - - for (i = 0, length = iobuf->length; length > 0; - length -= pga[i].count, offset += pga[i].count, i++) { /*i last!*/ - pga[i].pg = iobuf->maplist[i]; - pga[i].off = offset; - /* To the end of the page, or the length, whatever is less */ - pga[i].count = min_t(int, PAGE_SIZE - (offset & ~PAGE_MASK), - length); - pga[i].flag = flags; - CDEBUG(D_PAGE, "page %d (%p), offset "LPU64", count %u\n", - i, pga[i].pg, pga[i].off, pga[i].count); - if (rw == READ) { - //POISON(kmap(iobuf->maplist[i]), 0xc5, PAGE_SIZE); - //kunmap(iobuf->maplist[i]); - } - } - - set->brw_callback = ll_brw_sync_wait; - rc = obd_brw(rw == WRITE ? OBD_BRW_WRITE : OBD_BRW_READ, - ll_i2obdconn(inode), lsm, iobuf->nr_pages, pga, set, NULL); - if (rc) { - CDEBUG(rc == -ENOSPC ? D_INODE : D_ERROR, - "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 = iobuf->length; - - OBD_FREE(pga, sizeof(*pga) * iobuf->nr_pages); - RETURN(rc); -} -#endif - -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; - -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)) - spin_lock(&pagecache_lock); - - spin_unlock(&pagecache_lock); -#endif - - - 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, -#endif - 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 613c42f..0000000 --- a/lustre/llite/super.c +++ /dev/null @@ -1,745 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Lustre Light Super operations - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#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; - -/* /proc/lustre/llite root that tracks llite mount points */ -struct proc_dir_entry *proc_lustre_fs_root = NULL; -/* lproc_llite.c */ -extern int lprocfs_register_mountpoint(struct proc_dir_entry *parent, - struct super_block *sb, - char *osc, char *mdc); - -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 *); - -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; - struct obd_uuid param_uuid; - - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - OBD_ALLOC(sbi, sizeof(*sbi)); - if (!sbi) - 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); - } - - strncpy(param_uuid.uuid, mdc, sizeof(param_uuid.uuid)); - obd = class_uuid2obd(¶m_uuid); - 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); - - strncpy(param_uuid.uuid, osc, sizeof(param_uuid.uuid)); - obd = class_uuid2obd(¶m_uuid); - 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; - - if (proc_lustre_fs_root) { - err = lprocfs_register_mountpoint(proc_lustre_fs_root, sb, - osc, mdc); - if (err < 0) - CERROR("could not register mount in /proc/lustre"); - } - -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)); - - 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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - 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); - - if (sbi->ll_proc_root) { - lprocfs_remove(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)); - - 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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - 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) - CERROR("clearing in-use inode %lu: count = %d\n", - inode->i_ino, atomic_read(&inode->i_count)); - - if (lli->lli_smd) - obd_free_memmd(&sbi->ll_osc_conn, &lli->lli_smd); - - if (lli->lli_symlink_name) { - OBD_FREE(lli->lli_symlink_name, - strlen(lli->lli_symlink_name) + 1); - lli->lli_symlink_name = NULL; - } - - EXIT; -} - -#if 0 -static void ll_delete_inode(struct inode *inode) -{ - ENTRY; - CDEBUG(D_VFSTRACE, "VFS Op\n"); - if (S_ISREG(inode->i_mode)) { - int err; - struct obdo *oa; - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - - /* mcreate with no open */ - if (!lsm) - GOTO(out, 0); - - 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; - obdo_from_inode(oa, inode, OBD_MD_FLID | OBD_MD_FLTYPE); - - err = obd_destroy(ll_i2obdconn(inode), oa, lsm, NULL); - obdo_free(oa); - if (err) - CDEBUG(D_INODE, - "inode %lu obd_destroy objid "LPX64" error %d\n", - inode->i_ino, lsm->lsm_object_id, err); - } -out: - clear_inode(inode); - EXIT; -} -#endif - -/* 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 = 0; - ENTRY; - - /* change incore inode */ - ll_attr2inode(inode, attr, do_trunc); - - /* Don't send size changes to MDS to avoid "fast EA" problems, and - * also avoid a pointless RPC (we get file size from OST anyways). - */ - attr->ia_valid &= ~ATTR_SIZE; - if (attr->ia_valid) { - err = mdc_setattr(&sbi->ll_mdc_conn, inode, attr, NULL, 0, - &request); - if (err) - CERROR("mdc_setattr fails: err = %d\n", err); - - ptlrpc_req_finished(request); - if (S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_MTIME_SET) { - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - struct obdo oa; - int err2; - - CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n", - inode->i_ino, attr->ia_mtime); - oa.o_id = lsm->lsm_object_id; - oa.o_mode = S_IFREG; - oa.o_valid = OBD_MD_FLID |OBD_MD_FLTYPE |OBD_MD_FLMTIME; - oa.o_mtime = attr->ia_mtime; - err2 = obd_setattr(&sbi->ll_osc_conn, &oa, lsm, NULL); - if (err2) { - CERROR("obd_setattr fails: rc=%d\n", err); - if (!err) - err = err2; - } - } - } - - RETURN(err); -} - -int ll_setattr_raw(struct inode *inode, struct iattr *attr) -{ - struct ptlrpc_request *request = NULL; - struct ll_sb_info *sbi = ll_i2sbi(inode); - int err = 0; - ENTRY; - - if ((attr->ia_valid & ATTR_SIZE)) { - err = vmtruncate(inode, attr->ia_size); - if (err) - RETURN(err); - } - - /* Don't send size changes to MDS to avoid "fast EA" problems, and - * also avoid a pointless RPC (we get file size from OST anyways). - */ - attr->ia_valid &= ~ATTR_SIZE; - if (!attr->ia_valid) - RETURN(0); - - err = mdc_setattr(&sbi->ll_mdc_conn, inode, attr, NULL, 0, - &request); - if (err) - CERROR("mdc_setattr fails: err = %d\n", err); - - ptlrpc_req_finished(request); - - if (S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_MTIME_SET) { - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - struct obdo oa; - int err2; - - CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n", - inode->i_ino, attr->ia_mtime); - oa.o_id = lsm->lsm_object_id; - oa.o_mode = S_IFREG; - oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMTIME; - oa.o_mtime = attr->ia_mtime; - err2 = obd_setattr(&sbi->ll_osc_conn, &oa, lsm, NULL); - if (err2) { - CERROR("obd_setattr fails: rc=%d\n", err); - if (!err) - err = err2; - } - } - RETURN(err); -} - -int ll_setattr(struct dentry *de, struct iattr *attr) -{ - int rc = inode_change_ok(de->d_inode, attr); - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - 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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - 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, - struct lov_mds_md *lmm) -{ - struct ll_inode_info *lli = ll_i2info(inode); - - if (lmm != NULL) - obd_unpackmd(ll_i2obdconn(inode), &lli->lli_smd, lmm); - - 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; - if (body->valid & OBD_MD_FLBLOCKS) - inode->i_blocks = body->blocks; -} - -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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - sema_init(&lli->lli_open_sem, 1); - - LASSERT(!lli->lli_smd); - - /* core attributes first */ - ll_update_inode(inode, body, lic ? lic->lic_lmm : NULL); - - /* 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, NULL); - if (rc) { - CERROR("ll_file_size: %d\n", rc); - ll_clear_inode(inode); - 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 { - inode->i_op = &ll_special_inode_operations; - 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 "LPU64" op %d to %s:%d\n", - req->rq_xid, req->rq_reqmsg->opc, - req->rq_connection->c_remote_uuid.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; - CDEBUG(D_VFSTRACE, "VFS Op\n"); - - 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 -}; - -static struct file_system_type lustre_lite_fs_type = { - name: "lustre_lite", - fs_flags: 0, - read_super: ll_read_super, - owner: THIS_MODULE, -}; - -static int __init init_lustre_lite(void) -{ - printk(KERN_INFO "Lustre Lite Client File System; " - "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; - - proc_lustre_fs_root = proc_lustre_root ? proc_mkdir("llite", proc_lustre_root) : NULL; - - 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); - - if (proc_lustre_fs_root) { - lprocfs_remove(proc_lustre_fs_root); - proc_lustre_fs_root = NULL; - } -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Lite Client File System"); -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 f77fdea..0000000 --- a/lustre/llite/super25.c +++ /dev/null @@ -1,760 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Lustre Light Super operations - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define DEBUG_SUBSYSTEM S_LLITE - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -#include -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; - -/* /proc/lustre/llite root that tracks llite mount points */ -struct proc_dir_entry *proc_lustre_fs_root = NULL; -/* lproc_llite.c */ -extern int lprocfs_register_mountpoint(struct proc_dir_entry *parent, - struct super_block *sb, - char *osc, char *mdc); - -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 int 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; - struct obd_uuid param_uuid; - - ENTRY; - - OBD_ALLOC(sbi, sizeof(*sbi)); - if (!sbi) - RETURN(-ENOMEM); - - 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->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); - } - - strncpy(param_uuid.uuid, mdc, sizeof(param_uuid.uuid)); - obd = class_uuid2obd(¶m_uuid); - 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; - root = iget5_locked(sb, sbi->ll_rootino, NULL, - ll_read_inode2, &lic); - - if (root) { - sb->s_root = d_alloc_root(root); - root->i_state &= ~(I_LOCK | I_NEW); - } else { - CERROR("lustre_lite: bad iget4 for root\n"); - GOTO(out_cdb, sb = NULL); - } - - ptlrpc_req_finished(request); - request = NULL; - - if (proc_lustre_fs_root) { - err = lprocfs_register_mountpoint(proc_lustre_fs_root, sb, - osc, mdc); - if (err < 0) - CERROR("could not register mount in /proc/lustre"); - } - -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)); - - 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 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 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); - - if (sbi->ll_proc_root) { - lprocfs_remove(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)); - - 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; - -#warning "Is there a reason we don't do this in 2.5, but we do in 2.4?" -#if 0 - 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 */ - } - } -#endif - - if (atomic_read(&inode->i_count) != 0) - CERROR("clearing in-use inode %lu: count = %d\n", - inode->i_ino, atomic_read(&inode->i_count)); - - if (lli->lli_smd) - obd_free_memmd(&sbi->ll_osc_conn, &lli->lli_smd); - - if (lli->lli_symlink_name) { - OBD_FREE(lli->lli_symlink_name,strlen(lli->lli_symlink_name)+1); - lli->lli_symlink_name = NULL; - } - - EXIT; -} - -#if 0 -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; - - /* mcreate with no open */ - if (!lsm) - GOTO(out, 0); - - 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_FLTYPE; - - err = obd_destroy(ll_i2obdconn(inode), oa, lsm); - obdo_free(oa); - if (err) - CDEBUG(D_SUPER, "obd destroy objid "LPX64" error %d\n", - lsm->lsm_object_id, err); - } -out: - clear_inode(inode); - EXIT; -} -#endif - -/* 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 = 0; - - ENTRY; - - /* change incore inode */ - ll_attr2inode(inode, attr, do_trunc); - - /* Don't send size changes to MDS to avoid "fast EA" problems, and - * also avoid a pointless RPC (we get file size from OST anyways). - */ - attr->ia_valid &= ~ATTR_SIZE; - if (attr->ia_valid) { - err = mdc_setattr(&sbi->ll_mdc_conn, inode, attr, NULL, 0, - &request); - if (err) - CERROR("mdc_setattr fails: err = %d\n", err); - - ptlrpc_req_finished(request); - if (S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_MTIME_SET) { - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - struct obdo oa; - int err2; - - CDEBUG(D_ERROR, "setting mtime on OST\n"); - oa.o_id = lsm->lsm_object_id; - oa.o_mode = S_IFREG; - oa.o_valid = OBD_MD_FLID |OBD_MD_FLTYPE |OBD_MD_FLMTIME; - oa.o_mtime = attr->ia_mtime.tv_sec; - err2 = obd_setattr(&sbi->ll_osc_conn, &oa, lsm, NULL); - if (err2) { - CERROR("obd_setattr fails: rc=%d\n", err); - if (!err) - err = err2; - } - } - } - - RETURN(err); -} - -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, - struct lov_mds_md *lmm) -{ - struct ll_inode_info *lli = ll_i2info(inode); - - if (lmm != NULL) - obd_unpackmd(ll_i2obdconn(inode), &lli->lli_smd, lmm); - - if (body->valid & OBD_MD_FLID) - inode->i_ino = body->ino; - if (body->valid & OBD_MD_FLATIME) - inode->i_atime.tv_sec = body->atime; - if (body->valid & OBD_MD_FLMTIME) - inode->i_mtime.tv_sec = body->mtime; - if (body->valid & OBD_MD_FLCTIME) - inode->i_ctime.tv_sec = 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; - if (body->valid & OBD_MD_FLBLOCKS) - inode->i_blocks = body->blocks; -} - -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); - - LASSERT(!lli->lli_smd); - - /* core attributes first */ - ll_update_inode(inode, body, lic ? lic->lic_lmm : NULL); - - /* Get the authoritative file size */ - if (lli->lli_smd && S_ISREG(inode->i_mode)) { - rc = ll_file_size(inode, lli->lli_smd, NULL); - if (rc) { - CERROR("ll_file_size: %d\n", rc); - ll_clear_inode(inode); - make_bad_inode(inode); - RETURN(rc); - } - } - - /* 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_anon_super, -}; - -static int __init init_lustre_lite(void) -{ - int rc; - printk(KERN_INFO "Lustre Lite Client File System; " - "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; - } - - proc_lustre_fs_root = proc_lustre_root ? - proc_mkdir("llite", proc_lustre_root) : NULL; - - 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); - if (proc_lustre_fs_root) { - lprocfs_remove(proc_lustre_fs_root); - proc_lustre_fs_root = NULL; - } -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Lite Client File System"); -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 6ebe7de..0000000 --- a/lustre/llite/symlink.c +++ /dev/null @@ -1,170 +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 -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#endif -#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 %lu: 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; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - /* 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); -} - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -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 = 0, mode = 0, rc; - char *symname; - ENTRY; - - CDEBUG(D_VFSTRACE, "VFS Op\n"); - if (it != NULL) { - op = it->it_op; - mode = it->it_mode; - - ll_intent_release(dentry, it); - } - - down(&lli->lli_open_sem); - rc = ll_readlink_internal(inode, &request, &symname); - up(&lli->lli_open_sem); - if (rc) - GOTO(out, rc); - - if (it != NULL) { - it->it_op = op; - it->it_mode = mode; - } - - rc = vfs_follow_link_it(nd, symname, it); - out: - ptlrpc_req_finished(request); - - RETURN(rc); -} -#else -static int ll_follow_link(struct dentry *dentry, struct nameidata *nd) -{ - struct inode *inode = dentry->d_inode; - struct ll_inode_info *lli = ll_i2info(inode); - struct ptlrpc_request *request; - int op = 0, mode = 0, rc; - char *symname; - ENTRY; - - op = nd->it.it_op; - mode = nd->it.it_mode; - - ll_intent_release(dentry, &nd->it); - - down(&lli->lli_open_sem); - - rc = ll_readlink_internal(inode, &request, &symname); - if (rc) - GOTO(out, rc); - - nd->it.it_op = op; - nd->it.it_mode = mode; - - rc = vfs_follow_link(nd, symname); - out: - up(&lli->lli_open_sem); - ptlrpc_req_finished(request); - - RETURN(rc); -} -#endif - -extern int ll_inode_revalidate(struct dentry *dentry); -extern int ll_setattr(struct dentry *de, struct iattr *attr); -struct inode_operations ll_fast_symlink_inode_operations = { - readlink: ll_readlink, - setattr: ll_setattr, - setattr_raw: ll_setattr_raw, - follow_link2: ll_follow_link, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - revalidate: ll_inode_revalidate -#endif -}; diff --git a/lustre/llite/sysctl.c b/lustre/llite/sysctl.c deleted file mode 100644 index b626046..0000000 --- a/lustre/llite/sysctl.c +++ /dev/null @@ -1,70 +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 -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#include -#endif -#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 6b647b4..0000000 --- a/lustre/lov/Makefile.am +++ /dev/null @@ -1,24 +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= - -if LIBLUSTRE -lib_LIBRARIES = liblov.a -LINX=client.c -liblov_a_SOURCES = lov_obd.c lov_pack.c $(LINX) -else -MODULE = lov -modulefs_DATA = lov.o -EXTRA_PROGRAMS = lov -LINX=client.c -lov_SOURCES = lov_obd.c lov_pack.c lproc_lov.c $(LINX) -endif - - -client.c: - test -e client.c || ln -sf $(top_srcdir)/lib/client.c - -include $(top_srcdir)/Rules diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c deleted file mode 100644 index 0e7ad82..0000000 --- a/lustre/lov/lov_obd.c +++ /dev/null @@ -1,1691 +0,0 @@ - /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * Author: Phil Schwan - * Peter Braam - * 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_LOV -#ifdef __KERNEL__ -#include -#include -#include -#include -#include -#include -#else -#include -#endif - -#include -#include -#include -#include -#include /* for LL_IOC_LOV_[GS]ETSTRIPE */ -#include -#include -#include -#include - -static kmem_cache_t *lov_file_cache; - -struct lov_file_handles { - struct list_head lfh_list; - __u64 lfh_cookie; - int lfh_count; - char *lfh_data; /* an array of opaque data saved on behalf of - * each osc, FD_OSTDATA_SIZE bytes for each */ -}; - -struct lov_lock_handles { - __u64 llh_cookie; - struct lustre_handle llh_handles[0]; -}; - -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); -extern int lov_setstripe(struct lustre_handle *conn, - struct lov_stripe_md **lsmp, struct lov_mds_md *lmmu); -extern int lov_getstripe(struct lustre_handle *conn, struct lov_mds_md *lmmu, - struct lov_stripe_md *lsm); - -/* obd methods */ -int lov_attach(struct obd_device *dev, obd_count len, void *data) -{ - struct lprocfs_static_vars lvars; - - lprocfs_init_vars(&lvars); - return lprocfs_obd_attach(dev, lvars.obd_vars); -} - -int lov_detach(struct obd_device *dev) -{ - return lprocfs_obd_detach(dev); -} - -static int lov_connect(struct lustre_handle *conn, struct obd_device *obd, - struct obd_uuid *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 lov_tgt_desc *tgts; - struct obd_export *exp; - struct lustre_handle mdc_conn; - struct obd_uuid lov_mds_uuid = {"LOV_MDS_UUID"}; - char *tmp; - int rc, rc2, i; - ENTRY; - - rc = class_connect(conn, obd, cluuid); - if (rc) - RETURN(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); - spin_lock_init(&exp->exp_lov_data.led_lock); - INIT_LIST_HEAD(&exp->exp_lov_data.led_open_head); - - /* retrieve LOV metadata from MDS */ - rc = obd_connect(&mdc_conn, lov->mdcobd, &lov_mds_uuid, 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(desc->ld_uuid.uuid) * desc->ld_tgt_count){ - CERROR("LOV desc: invalid uuid array returned\n"); - GOTO(out_conn, rc = -EINVAL); - } - - if (memcmp(obd->obd_uuid.uuid, desc->ld_uuid.uuid, - sizeof(desc->ld_uuid.uuid))) { - CERROR("LOV desc: uuid %s not on mds device (%s)\n", - obd->obd_uuid.uuid, desc->ld_uuid.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); - } - - tmp = lustre_msg_buf(req->rq_repmsg, 1); - for (i = 0, tgts = lov->tgts; i < desc->ld_tgt_count; i++, tgts++) { - struct obd_uuid *uuid = &tgts->uuid; - struct obd_device *tgt_obd; - struct obd_uuid lov_osc_uuid = { "LOV_OSC_UUID" }; - - obd_str2uuid(uuid, tmp); - tgt_obd = client_tgtuuid2obd(uuid); - tmp += sizeof(uuid->uuid); - - if (!tgt_obd) { - CERROR("Target %s not attached\n", uuid->uuid); - GOTO(out_disc, rc = -EINVAL); - } - - if (!(tgt_obd->obd_flags & OBD_SET_UP)) { - CERROR("Target %s not set up\n", uuid->uuid); - GOTO(out_disc, rc = -EINVAL); - } - - rc = obd_connect(&tgts->conn, tgt_obd, &lov_osc_uuid, recovd, - recover); - - if (rc) { - CERROR("Target %s connect error %d\n", uuid->uuid, rc); - GOTO(out_disc, rc); - } - - rc = obd_iocontrol(IOC_OSC_REGISTER_LOV, &tgts->conn, - sizeof(struct obd_device *), obd, NULL); - if (rc) { - CERROR("Target %s REGISTER_LOV error %d\n", - uuid->uuid, rc); - obd_disconnect(&tgts->conn); - GOTO(out_disc, rc); - } - - desc->ld_active_tgt_count++; - tgts->active = 1; - } - - mdc->cl_max_mds_easize = obd_size_wiremd(conn, NULL); - - out: - ptlrpc_req_finished(req); - RETURN(rc); - - out_disc: - while (i-- > 0) { - struct obd_uuid uuid; - --tgts; - --desc->ld_active_tgt_count; - tgts->active = 0; - obd_str2uuid(&uuid, tgts->uuid.uuid); - rc2 = obd_disconnect(&tgts->conn); - if (rc2) - CERROR("error: LOV target %s disconnect on OST idx %d: " - "rc = %d\n", uuid.uuid, i, rc2); - } - OBD_FREE(lov->tgts, lov->bufsize); - out_conn: - class_disconnect(conn); - 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.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); - spin_lock(&exp->exp_lov_data.led_lock); - 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_data, lfh->lfh_count * FD_OSTDATA_SIZE); - PORTAL_SLAB_FREE(lfh, lov_file_cache, sizeof(*lfh)); - } - spin_unlock(&exp->exp_lov_data.led_lock); - - out_local: - rc = class_disconnect(conn); - 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, struct obd_uuid *uuid, - int activate) -{ - struct obd_device *obd; - struct lov_tgt_desc *tgt; - int i, rc = 0; - ENTRY; - - CDEBUG(D_INFO, "Searching in lov %p for uuid %s (activate=%d)\n", - lov, uuid->uuid, activate); - - spin_lock(&lov->lov_lock); - for (i = 0, tgt = lov->tgts; i < lov->desc.ld_tgt_count; i++, tgt++) { - CDEBUG(D_INFO, "lov idx %d is %s conn "LPX64"\n", - i, tgt->uuid.uuid, tgt->conn.addr); - if (strncmp(uuid->uuid, tgt->uuid.uuid, sizeof(uuid->uuid)) == 0) - break; - } - - if (i == lov->desc.ld_tgt_count) - GOTO(out, rc = -EINVAL); - - obd = class_conn2obd(&tgt->conn); - if (obd == NULL) { - LBUG(); - GOTO(out, rc = -ENOTCONN); - } - - CDEBUG(D_INFO, "Found OBD %s=%s device %d (%p) type %s at LOV idx %d\n", - obd->obd_name, obd->obd_uuid.uuid, obd->obd_minor, obd, - obd->obd_type->typ_name, i); - if (strcmp(obd->obd_type->typ_name, "osc") != 0) { - LBUG(); - GOTO(out, rc = -EBADF); - } - - if (tgt->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"); - - tgt->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--; - } - -#warning "FIXME: walk open files list for objects that need opening" - 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; - struct obd_uuid uuid; - 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); - obd_str2uuid(&uuid, data->ioc_inlbuf1); - lov->mdcobd = class_uuid2obd(&uuid); - if (!lov->mdcobd) { - CERROR("LOV %s cannot locate MDC %s\n", obd->obd_uuid.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_trans_info *oti) -{ - 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; - int first = 1, obj_alloc = 0; - int rc = 0, i; - ENTRY; - - LASSERT(ea); - - if (!export) - RETURN(-EINVAL); - - lov = &export->exp_obd->u.lov; - - if (!lov->desc.ld_active_tgt_count) - RETURN(-EIO); - - tmp = obdo_alloc(); - if (!tmp) - RETURN(-ENOMEM); - - lsm = *ea; - - if (!lsm) { - rc = obd_alloc_memmd(conn, &lsm); - if (rc < 0) - GOTO(out_tmp, rc); - - rc = 0; - lsm->lsm_magic = LOV_MAGIC; - } - - ost_count = lov->desc.ld_tgt_count; - - 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; - - if (!*ea || 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); - - ost_idx = (stripe_offset + sub_offset) % ost_count; - } else - ost_idx = lsm->lsm_stripe_offset; - - CDEBUG(D_INODE, "allocating %d subobjs for objid "LPX64" at idx %d\n", - lsm->lsm_stripe_count, lsm->lsm_object_id, ost_idx); - - loi = lsm->lsm_oinfo; - for (i = 0; i < ost_count; i++, ost_idx = (ost_idx + 1) % ost_count) { - struct lov_stripe_md obj_md; - struct lov_stripe_md *obj_mdp = &obj_md; - int err; - - if (lov->tgts[ost_idx].active == 0) { - CDEBUG(D_HA, "lov idx %d inactive\n", ost_idx); - continue; - } - - /* create data objects with "parent" OA */ - memcpy(tmp, oa, sizeof(*tmp)); - /* XXX: LOV STACKING: use real "obj_mdp" sub-data */ - err = obd_create(&lov->tgts[ost_idx].conn, tmp, &obj_mdp, oti); - if (err) { - if (lov->tgts[ost_idx].active) { - CERROR("error creating objid "LPX64" sub-object" - " on OST idx %d/%d: rc = %d\n", oa->o_id, - ost_idx, lsm->lsm_stripe_count, err); - if (err > 0) { - CERROR("obd_create returned invalid " - "err %d\n", err); - err = -EIO; - } - if (!rc) - rc = err; - } - continue; - } - loi->loi_id = tmp->o_id; - loi->loi_ost_idx = ost_idx; - CDEBUG(D_INODE, "objid "LPX64" has subobj "LPX64" at idx %d\n", - lsm->lsm_object_id, loi->loi_id, ost_idx); - - if (first) { - lsm->lsm_stripe_offset = ost_idx; - first = 0; - } - - ++obj_alloc; - ++loi; - - /* If we have allocated enough objects, we are OK */ - if (obj_alloc == lsm->lsm_stripe_count) { - rc = 0; - GOTO(out_done, rc); - } - } - - if (*ea) - GOTO(out_cleanup, rc); - else { - struct lov_stripe_md *lsm_new; - /* XXX LOV STACKING call into osc for sizes */ - int size = lov_stripe_md_size(obj_alloc); - - OBD_ALLOC(lsm_new, size); - if (!lsm_new) - GOTO(out_cleanup, rc = -ENOMEM); - memcpy(lsm_new, lsm, size); - lsm_new->lsm_stripe_count = obj_alloc; - - /* XXX LOV STACKING call into osc for sizes */ - OBD_FREE(lsm, lov_stripe_md_size(lsm->lsm_stripe_count)); - lsm = lsm_new; - } - out_done: - *ea = lsm; - - out_tmp: - obdo_free(tmp); - return rc; - - out_cleanup: - while (obj_alloc-- > 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, 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); - } - 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 obd_trans_info *oti) -{ - 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 %#x != %#x\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) { - CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx); - /* 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_data + i * FD_OSTDATA_SIZE, - FD_OSTDATA_SIZE); - else - tmp.o_valid &= ~OBD_MD_FLHANDLE; - err = obd_destroy(&lov->tgts[loi->loi_ost_idx].conn, &tmp, - NULL, 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 *set) -{ - if (*set) { - 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; - } else { - obdo_cpy_md(tgt, src, valid); - if (valid & OBD_MD_FLSIZE) - tgt->o_size = lov_stripe_size(lsm,src->o_size,stripeno); - *set = 1; - } -} - -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 set = 0; - ENTRY; - - if (!lsm) { - CERROR("LOV requires striping ea\n"); - RETURN(-EINVAL); - } - - if (lsm->lsm_magic != LOV_MAGIC) { - CERROR("LOV striping magic bad %#x != %#x\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)); - - CDEBUG(D_INFO, "objid "LPX64": %ux%u byte stripes\n", - lsm->lsm_object_id, lsm->lsm_stripe_count, lsm->lsm_stripe_size); - 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) { - CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx); - 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_data + i * FD_OSTDATA_SIZE, - FD_OSTDATA_SIZE); - else - tmp.o_valid &= ~OBD_MD_FLHANDLE; - - err = obd_getattr(&lov->tgts[loi->loi_ost_idx].conn, &tmp,NULL); - if (err) { - if (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); - } - } else { - lov_merge_attrs(oa, &tmp, tmp.o_valid, lsm, i, &set); - } - } - - RETURN(set ? 0 : -EIO); -} - -static int lov_setattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm, struct obd_trans_info *oti) -{ - 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, set = 0; - ENTRY; - - if (!lsm) { - CERROR("LOV requires striping ea\n"); - RETURN(-EINVAL); - } - - if (lsm->lsm_magic != LOV_MAGIC) { - CERROR("LOV striping magic bad %#x != %#x\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)); - - /* for now, we only expect mtime updates here */ - LASSERT(!(oa->o_valid & ~(OBD_MD_FLID |OBD_MD_FLTYPE |OBD_MD_FLMTIME))); - - 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; - - if (lov->tgts[loi->loi_ost_idx].active == 0) { - CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx); - continue; - } - - obdo_cpy_md(tmp, oa, oa->o_valid); - - if (lfh) - memcpy(obdo_handle(tmp), - lfh->lfh_data + i * FD_OSTDATA_SIZE, - FD_OSTDATA_SIZE); - 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, NULL); - if (err) { - if (lov->tgts[loi->loi_ost_idx].active) { - 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; - } - } else - set = 1; - } - obdo_free(tmp); - if (!set && !rc) - rc = -EIO; - RETURN(rc); -} - -static int lov_open(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm, struct obd_trans_info *oti) -{ - 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 set = 0; - 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 %#x != %#x\n", - lsm->lsm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - - if (!export || !export->exp_obd) - RETURN(-ENODEV); - - tmp = obdo_alloc(); - if (!tmp) - RETURN(-ENOMEM); - - PORTAL_SLAB_ALLOC(lfh, lov_file_cache, sizeof(*lfh)); - if (!lfh) - GOTO(out_tmp, rc = -ENOMEM); - OBD_ALLOC(lfh->lfh_data, lsm->lsm_stripe_count * FD_OSTDATA_SIZE); - if (!lfh->lfh_data) - 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) { - CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx); - 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, NULL); - if (rc) { - if (!lov->tgts[loi->loi_ost_idx].active) - continue; - 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, &set); - - if (tmp->o_valid & OBD_MD_FLHANDLE) - memcpy(lfh->lfh_data + i * FD_OSTDATA_SIZE, - obdo_handle(tmp), FD_OSTDATA_SIZE); - } - - 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; - spin_lock(&export->exp_lov_data.led_lock); - list_add(&lfh->lfh_list, &export->exp_lov_data.led_open_head); - spin_unlock(&export->exp_lov_data.led_lock); - - if (!set && !rc) - rc = -EIO; -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_data + i * FD_OSTDATA_SIZE, - FD_OSTDATA_SIZE); - - err = obd_close(&lov->tgts[loi->loi_ost_idx].conn, tmp, - NULL, NULL); - if (err && lov->tgts[loi->loi_ost_idx].active) { - 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_data, lsm->lsm_stripe_count * FD_OSTDATA_SIZE); -out_lfh: - PORTAL_SLAB_FREE(lfh, lov_file_cache, sizeof(*lfh)); - goto out_tmp; -} - -static int lov_close(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *lsm, struct obd_trans_info *oti) -{ - 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 %#x != %#x\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) { - CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx); - 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_data + i * FD_OSTDATA_SIZE, - FD_OSTDATA_SIZE); - else - tmp.o_valid &= ~OBD_MD_FLHANDLE; - - err = obd_close(&lov->tgts[loi->loi_ost_idx].conn, &tmp, - NULL, NULL); - if (err) { - if (lov->tgts[loi->loi_ost_idx].active) { - 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) { - spin_lock(&export->exp_lov_data.led_lock); - list_del(&lfh->lfh_list); - spin_unlock(&export->exp_lov_data.led_lock); - - OBD_FREE(lfh->lfh_data, lsm->lsm_stripe_count*FD_OSTDATA_SIZE); - PORTAL_SLAB_FREE(lfh, lov_file_cache, sizeof(*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 obd_trans_info *oti) -{ - 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 %#x != %#x\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_data + i * FD_OSTDATA_SIZE, - FD_OSTDATA_SIZE); - else - tmp.o_valid &= ~OBD_MD_FLHANDLE; - - err = obd_punch(&lov->tgts[loi->loi_ost_idx].conn, &tmp, NULL, - starti, endi, NULL); - if (err) { - if (lov->tgts[loi->loi_ost_idx].active) { - 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 obd_trans_info *oti) -{ - 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 %#x != %#x\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 (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, oti); - 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 struct lov_lock_handles *lov_newlockh(struct lov_stripe_md *lsm) -{ - struct lov_lock_handles *lov_lockh; - - OBD_ALLOC(lov_lockh, sizeof(*lov_lockh) + - sizeof(*lov_lockh->llh_handles) * lsm->lsm_stripe_count); - if (!lov_lockh) - return NULL; - - get_random_bytes(&lov_lockh->llh_cookie, sizeof(lov_lockh->llh_cookie)); - - return lov_lockh; -} - -/* We are only ever passed local lock handles here, so we do not need to - * validate (and we can't really because these structs are variable sized - * and therefore alloced, and not from a private slab). - * - * We just check because we can... - */ -static struct lov_lock_handles *lov_h2lovlockh(struct lustre_handle *handle) -{ - struct lov_lock_handles *lov_lockh = NULL; - - if (!handle || !handle->addr) - RETURN(NULL); - - lov_lockh = (struct lov_lock_handles *)(unsigned long)(handle->addr); - if (lov_lockh->llh_cookie != handle->cookie) - RETURN(NULL); - - return lov_lockh; -} - -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 *lockh) -{ - struct obd_export *export = class_conn2export(conn); - struct lov_lock_handles *lov_lockh = NULL; - struct lustre_handle *lov_lockhp; - 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 %#x != %#x\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); - - if (lsm->lsm_stripe_count > 1) { - lov_lockh = lov_newlockh(lsm); - if (!lov_lockh) - RETURN(-ENOMEM); - - lockh->addr = (__u64)(unsigned long)lov_lockh; - lockh->cookie = lov_lockh->llh_cookie; - lov_lockhp = lov_lockh->llh_handles; - } else { - lov_lockhp = lockh; - } - - lov = &export->exp_obd->u.lov; - for (i = 0, loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; - i++, loi++, lov_lockhp++) { - struct ldlm_extent *extent = (struct ldlm_extent *)cookie; - struct ldlm_extent sub_ext; - - if (lov->tgts[loi->loi_ost_idx].active == 0) { - CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx); - 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 /* || !active */) - continue; - - /* XXX LOV STACKING: submd should be from the subobj */ - submd.lsm_object_id = loi->loi_id; - 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, lov_lockhp); - // XXX add a lock debug statement here - if (rc) - memset(lov_lockhp, 0, sizeof(*lov_lockhp)); - 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: - while (loi--, lov_lockhp--, i-- > 0) { - struct lov_stripe_md submd; - int err; - - if (lov_lockhp->cookie == 0 || - lov->tgts[loi->loi_ost_idx].active == 0) - continue; - - /* XXX LOV STACKING: submd should be from the subobj */ - submd.lsm_object_id = loi->loi_id; - submd.lsm_stripe_count = 0; - err = obd_cancel(&lov->tgts[loi->loi_ost_idx].conn, &submd, - mode, lov_lockhp); - if (err && lov->tgts[loi->loi_ost_idx].active) { - CERROR("error: cancelling objid "LPX64" on OST " - "idx %d after enqueue error: rc = %d\n", - loi->loi_id, loi->loi_ost_idx, err); - } - } - - if (lsm->lsm_stripe_count > 1) { - lov_lockh->llh_cookie = DEAD_HANDLE_MAGIC; - OBD_FREE(lov_lockh, sizeof(*lov_lockh) + - sizeof(*lov_lockh->llh_handles) * - lsm->lsm_stripe_count); - } - lockh->cookie = DEAD_HANDLE_MAGIC; - - RETURN(rc); -} - -static int lov_cancel(struct lustre_handle *conn, struct lov_stripe_md *lsm, - __u32 mode, struct lustre_handle *lockh) -{ - struct obd_export *export = class_conn2export(conn); - struct lov_lock_handles *lov_lockh = NULL; - struct lustre_handle *lov_lockhp; - 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 %#x != %#x\n", - lsm->lsm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - - if (!export || !export->exp_obd) - RETURN(-ENODEV); - - LASSERT(lockh); - if (lsm->lsm_stripe_count > 1) { - lov_lockh = lov_h2lovlockh(lockh); - if (!lov_lockh) { - CERROR("LOV: invalid lov lock handle %p\n", lockh); - RETURN(-EINVAL); - } - - lov_lockhp = lov_lockh->llh_handles; - } else - lov_lockhp = lockh; - - lov = &export->exp_obd->u.lov; - for (i = 0, loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; - i++, loi++, lov_lockhp++ ) { - struct lov_stripe_md submd; - int err; - - if (lov_lockhp->cookie == 0) { - CDEBUG(D_HA, "lov idx %d no lock?\n", loi->loi_ost_idx); - continue; - } - - /* XXX LOV STACKING: submd should be from the subobj */ - submd.lsm_object_id = loi->loi_id; - submd.lsm_stripe_count = 0; - err = obd_cancel(&lov->tgts[loi->loi_ost_idx].conn, &submd, - mode, lov_lockhp); - if (err) { - if (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; - } - } - } - - if (lsm->lsm_stripe_count > 1) { - lov_lockh->llh_cookie = DEAD_HANDLE_MAGIC; - OBD_FREE(lov_lockh, sizeof(*lov_lockh) + - sizeof(*lov_lockh->llh_handles) * - lsm->lsm_stripe_count); - } - lockh->cookie = DEAD_HANDLE_MAGIC; - - 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; - 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; - int err; - - 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) { - CDEBUG(D_HA, "lov idx %d inactive\n", i); - continue; - } - - err = obd_statfs(&lov->tgts[i].conn, &lov_sfs); - if (err) { - if (lov->tgts[i].active) { - CERROR("error: statfs OSC %s on OST idx %d: " - "err = %d\n", - lov->tgts[i].uuid.uuid, i, err); - if (!rc) - rc = err; - } - 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; - */ - } - } - if (!set && !rc) - rc = -EIO; - 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; - int i, count = lov->desc.ld_tgt_count; - struct obd_uuid *uuidp; - int rc; - - ENTRY; - - switch (cmd) { - case IOC_LOV_SET_OSC_ACTIVE: { - struct obd_ioctl_data *data = karg; - uuidp = (struct obd_uuid *)data->ioc_inlbuf1; - rc = lov_set_osc_active(lov, uuidp, data->ioc_offset); - break; - } - case OBD_IOC_LOV_GET_CONFIG: { - struct obd_ioctl_data *data = karg; - struct lov_tgt_desc *tgtdesc; - struct lov_desc *desc; - 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->uuid) * count > data->ioc_inllen2) { - OBD_FREE(buf, len); - RETURN(-EINVAL); - } - - desc = (struct lov_desc *)data->ioc_inlbuf1; - memcpy(desc, &(lov->desc), sizeof(*desc)); - - uuidp = (struct obd_uuid *)data->ioc_inlbuf2; - tgtdesc = lov->tgts; - for (i = 0; i < count; i++, uuidp++, tgtdesc++) - obd_str2uuid(uuidp, tgtdesc->uuid.uuid); - - rc = copy_to_user((void *)uarg, buf, len); - if (rc) - rc = -EFAULT; - OBD_FREE(buf, len); - break; - } - case LL_IOC_LOV_SETSTRIPE: - rc = lov_setstripe(conn, karg, uarg); - break; - case LL_IOC_LOV_GETSTRIPE: - rc = lov_getstripe(conn, karg, uarg); - break; - default: { - int set = 0; - if (count == 0) - RETURN(-ENOTTY); - rc = 0; - for (i = 0; i < count; i++) { - int err; - - err = obd_iocontrol(cmd, &lov->tgts[i].conn, - len, karg, uarg); - if (err) { - if (lov->tgts[i].active) { - CERROR("error: iocontrol OSC %s on OST" - "idx %d: err = %d\n", - lov->tgts[i].uuid.uuid, i, err); - if (!rc) - rc = err; - } - } else - set = 1; - } - if (!set && !rc) - rc = -EIO; - } - } - - RETURN(rc); -} - -struct obd_ops lov_obd_ops = { - o_owner: THIS_MODULE, - 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 -}; - -int __init lov_init(void) -{ - struct lprocfs_static_vars lvars; - int rc; - - printk(KERN_INFO "Lustre Logical Object Volume driver; " - "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); - - lprocfs_init_vars(&lvars); - rc = class_register_type(&lov_obd_ops, lvars.module_vars, - 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); -} - -#ifdef __KERNEL__ -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Logical Object Volume OBD driver"); -MODULE_LICENSE("GPL"); - -module_init(lov_init); -module_exit(lov_exit); -#endif diff --git a/lustre/lov/lov_pack.c b/lustre/lov/lov_pack.c deleted file mode 100644 index 463dd72..0000000 --- a/lustre/lov/lov_pack.c +++ /dev/null @@ -1,352 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * 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. - * - * (Un)packing of OST/MDS requests - * - */ - -#define DEBUG_SUBSYSTEM S_LLITE -#ifndef __KERNEL__ -#include -#endif - -#include -#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); -} - -void lov_dump_lmm(int level, struct lov_mds_md *lmm) -{ - struct lov_object_id *loi; - int idx; - - CDEBUG(level, "objid "LPX64", magic %#08x, ost_count %u\n", - lmm->lmm_object_id, lmm->lmm_magic, lmm->lmm_ost_count); - CDEBUG(level,"stripe_size %u, stripe_count %u, stripe_offset %u\n", - lmm->lmm_stripe_size, lmm->lmm_stripe_count, - lmm->lmm_stripe_offset); - for (idx = 0, loi = lmm->lmm_objects; idx < lmm->lmm_ost_count; - idx++, loi++) - CDEBUG(level, "ost idx %u subobj "LPX64"\n", idx, - loi->l_object_id); -} - -#define LMM_ASSERT(test) \ -do { \ - if (!(test)) lov_dump_lmm(D_ERROR, lmm); \ - LASSERT(test); /* so we know what assertion failed */ \ -} while(0) - -/* 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) { - int i, max = 0; - if (lsm->lsm_magic != LOV_MAGIC) { - CERROR("bad mem LOV MAGIC: %#010x != %#010x\n", - lsm->lsm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - stripe_count = lsm->lsm_stripe_count; - - for (i = 0,loi = lsm->lsm_oinfo; i < stripe_count; i++,loi++) { - if (loi->loi_ost_idx > max) - max = loi->loi_ost_idx; - } - ost_count = max + 1; - } - - /* 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); - LASSERT(lsm->lsm_object_id); - lmm->lmm_stripe_size = (lsm->lsm_stripe_size); - lmm->lmm_stripe_offset = (lsm->lsm_stripe_offset); - lmm->lmm_ost_count = (ost_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 */ - LASSERT(loi->loi_id); - lmm->lmm_objects[loi->loi_ost_idx].l_object_id = (loi->loi_id); - } - - RETURN(lmm_size); -} - -static int lov_get_stripecnt(struct lov_obd *lov, int stripe_count) -{ - if (!stripe_count) - stripe_count = lov->desc.ld_default_stripe_count; - if (!stripe_count || stripe_count > lov->desc.ld_active_tgt_count) - stripe_count = lov->desc.ld_active_tgt_count; - - return stripe_count; -} - -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; - int ost_offset = 0; - int stripe_count; - int lsm_size; - int i; - ENTRY; - - if (lmm) { - /* endianness */ - if (lmm->lmm_magic != LOV_MAGIC) { - CERROR("bad wire LOV MAGIC: %#08x != %#08x\n", - lmm->lmm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } - stripe_count = (lmm->lmm_stripe_count); - LASSERT(stripe_count); - } else - stripe_count = lov_get_stripecnt(lov, 0); - - /* 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); - - ost_count = (lmm->lmm_ost_count); - - LMM_ASSERT(lsm->lsm_object_id); - LMM_ASSERT(ost_count); - - 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; - - LMM_ASSERT(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++; - } - LMM_ASSERT(loi - lsm->lsm_oinfo > 0); - LMM_ASSERT(loi - lsm->lsm_oinfo == stripe_count); - - RETURN(lsm_size); -} - -/* Configure object striping information on a new file. - * - * @lmmu 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. - * @lsmp is a pointer to an in-core stripe MD that needs to be filled in. - */ -int lov_setstripe(struct lustre_handle *conn, struct lov_stripe_md **lsmp, - struct lov_mds_md *lmmu) -{ - struct obd_device *obd = class_conn2obd(conn); - struct lov_obd *lov = &obd->u.lov; - struct lov_mds_md lmm; - struct lov_stripe_md *lsm; - int stripe_count; - int rc; - ENTRY; - - rc = copy_from_user(&lmm, lmmu, sizeof(lmm)); - if (rc) - RETURN(-EFAULT); - - if (lmm.lmm_magic != LOV_MAGIC) { - CERROR("bad wire LOV MAGIC: %#08x != %#08x\n", - lmm.lmm_magic, LOV_MAGIC); - RETURN(-EINVAL); - } -#if 0 /* the stripe_count/offset is "advisory", and it gets fixed later */ - if (lmm.lmm_stripe_count > lov->desc.ld_tgt_count && - lmm.lmm_stripe_count != 0xffffffff) { - CERROR("stripe count %u more than OST count %d\n", - lmm.lmm_stripe_count, lov->desc.ld_tgt_count); - RETURN(-EINVAL); - } - if (lmm.lmm_stripe_offset >= lov->desc.ld_tgt_count && - lmm.lmm_stripe_offset != 0xffffffff) { - CERROR("stripe offset %u more than max OST index %d\n", - lmm.lmm_stripe_offset, lov->desc.ld_tgt_count); - RETURN(-EINVAL); - } -#endif - if (lmm.lmm_stripe_size & (PAGE_SIZE - 1)) { - CERROR("stripe size %u not multiple of %lu\n", - lmm.lmm_stripe_size, PAGE_SIZE); - RETURN(-EINVAL); - } - stripe_count = lov_get_stripecnt(lov, lmm.lmm_stripe_count); - - if ((__u64)lmm.lmm_stripe_size * stripe_count > ~0UL) { - CERROR("stripe width %ux%u > %lu on 32-bit system\n", - lmm.lmm_stripe_size, (int)lmm.lmm_stripe_count, ~0UL); - RETURN(-EINVAL); - } - - /* XXX LOV STACKING call into osc for sizes */ - OBD_ALLOC(lsm, lov_stripe_md_size(stripe_count)); - if (!lsm) - RETURN(-ENOMEM); - - lsm->lsm_magic = LOV_MAGIC; - lsm->lsm_stripe_count = stripe_count; - lsm->lsm_stripe_offset = lmm.lmm_stripe_offset; - lsm->lsm_stripe_size = lmm.lmm_stripe_size; - - *lsmp = lsm; - - RETURN(rc); -} - -/* Retrieve object striping information. - * - * @lmmu is a pointer to an in-core 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. - */ -int lov_getstripe(struct lustre_handle *conn, struct lov_stripe_md *lsm, - struct lov_mds_md *lmmu) -{ - struct obd_device *obd = class_conn2obd(conn); - struct lov_obd *lov = &obd->u.lov; - struct lov_mds_md lmm, *lmmk = NULL; - int ost_count, rc, lmm_size; - ENTRY; - - if (!lsm) - RETURN(-ENODATA); - - rc = copy_from_user(&lmm, lmmu, sizeof(lmm)); - if (rc) - RETURN(-EFAULT); - - if (lmm.lmm_magic != LOV_MAGIC) - RETURN(-EINVAL); - - 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 = lov_packmd(conn, &lmmk, lsm); - if (rc < 0) - RETURN(rc); - - lmm_size = rc; - rc = 0; - - if (lmm_size && copy_to_user(lmmu, lmmk, lmm_size)) - rc = -EFAULT; - - obd_free_wiremd(conn, &lmmk); - - RETURN(rc); -} diff --git a/lustre/lov/lproc_lov.c b/lustre/lov/lproc_lov.c deleted file mode 100644 index 630148a..0000000 --- a/lustre/lov/lproc_lov.c +++ /dev/null @@ -1,177 +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 -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#endif -#include -#include - -#ifndef LPROCFS -struct lprocfs_vars lprocfs_module_vars[] = { {0} }; -struct lprocfs_vars lprocfs_obd_vars[] = { {0} }; -#else - -DEFINE_LPROCFS_STATFS_FCT(rd_blksize, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_kbytestotal, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_kbytesfree, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filestotal, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filesfree, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filegroups, obd_self_statfs); - -int rd_stripesize(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - struct obd_device *dev = (struct obd_device *)data; - struct lov_desc *desc; - - LASSERT(dev != NULL); - desc = &dev->u.lov.desc; - *eof = 1; - return snprintf(page, count, LPU64"\n", desc->ld_default_stripe_size); -} - -int rd_stripeoffset(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - struct obd_device *dev = (struct obd_device *)data; - struct lov_desc *desc; - - LASSERT(dev != NULL); - desc = &dev->u.lov.desc; - *eof = 1; - return snprintf(page, count, LPU64"\n", desc->ld_default_stripe_offset); -} - -int rd_stripetype(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - struct obd_device* dev = (struct obd_device*)data; - struct lov_desc *desc; - - LASSERT(dev != NULL); - desc = &dev->u.lov.desc; - *eof = 1; - return snprintf(page, count, "%u\n", desc->ld_pattern); -} - -int rd_stripecount(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - struct obd_device *dev = (struct obd_device *)data; - struct lov_desc *desc; - - LASSERT(dev != NULL); - desc = &dev->u.lov.desc; - *eof = 1; - return snprintf(page, count, "%u\n", desc->ld_default_stripe_count); -} - -int rd_numobd(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - struct obd_device *dev = (struct obd_device*)data; - struct lov_desc *desc; - - LASSERT(dev != NULL); - desc = &dev->u.lov.desc; - *eof = 1; - return snprintf(page, count, "%u\n", desc->ld_tgt_count); - -} - -int rd_activeobd(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - struct obd_device* dev = (struct obd_device*)data; - struct lov_desc *desc; - - LASSERT(dev != NULL); - desc = &dev->u.lov.desc; - *eof = 1; - return snprintf(page, count, "%u\n", desc->ld_active_tgt_count); -} - -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; - struct lov_obd *lov; - struct lov_tgt_desc *tgts; - - LASSERT(dev != NULL); - lov = &dev->u.lov; - tgts = lov->tgts; - LASSERT(tgts != NULL); - - for (i = 0; i < lov->desc.ld_tgt_count; i++, tgts++) { - int cur; - cur = snprintf(&page[len], count, "%d: %s %sACTIVE\n", - i, tgts->uuid.uuid, tgts->active ? "" : "IN"); - len += cur; - count -= cur; - } - - *eof = 1; - 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; - struct lov_obd *lov; - - LASSERT(dev != NULL); - lov = &dev->u.lov; - *eof = 1; - return snprintf(page, count, "%s\n", lov->mdcobd->obd_uuid.uuid); -} - -struct lprocfs_vars lprocfs_obd_vars[] = { - { "uuid", lprocfs_rd_uuid, 0, 0 }, - { "stripesize", rd_stripesize, 0, 0 }, - { "stripeoffset", rd_stripeoffset, 0, 0 }, - { "stripecount", rd_stripecount, 0, 0 }, - { "stripetype", rd_stripetype, 0, 0 }, - { "numobd", rd_numobd, 0, 0 }, - { "activeobd", rd_activeobd, 0, 0 }, - { "filestotal", rd_filestotal, 0, 0 }, - { "filesfree", rd_filesfree, 0, 0 }, - { "filegroups", rd_filegroups, 0, 0 }, - { "blocksize", rd_blksize, 0, 0 }, - { "kbytestotal", rd_kbytestotal, 0, 0 }, - { "kbytesfree", rd_kbytesfree, 0, 0 }, - { "target_obd", rd_target, 0, 0 }, - { "target_mdc", rd_mdc, 0, 0 }, - { 0 } -}; - -struct lprocfs_vars lprocfs_module_vars[] = { - { "num_refs", lprocfs_rd_numrefs, 0, 0 }, - { 0 } -}; - -#endif /* LPROCFS */ -LPROCFS_INIT_VARS(lprocfs_module_vars, lprocfs_obd_vars) 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 1d9c099..0000000 --- a/lustre/mdc/Makefile.am +++ /dev/null @@ -1,20 +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 client.c -mdc_SOURCES = mdc_request.c mdc_reint.c lproc_mdc.c $(LINX) - -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 3f81507..0000000 --- a/lustre/mdc/lproc_mdc.c +++ /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. - * - * 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 -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#endif -#include -#include - -#ifndef LPROCFS -struct lprocfs_vars lprocfs_obd_vars[] = { {0} }; -struct lprocfs_vars lprocfs_module_vars[] = { {0} }; -#else - -DEFINE_LPROCFS_STATFS_FCT(rd_blksize, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_kbytestotal, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_kbytesfree, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filestotal, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filesfree, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filegroups, obd_self_statfs); - -struct lprocfs_vars lprocfs_obd_vars[] = { - { "uuid", lprocfs_rd_uuid, 0, 0 }, - { "blocksize", rd_blksize, 0, 0 }, - { "kbytestotal", rd_kbytestotal, 0, 0 }, - { "kbytesfree", rd_kbytesfree, 0, 0 }, - { "filestotal", rd_filestotal, 0, 0 }, - { "filesfree", rd_filesfree, 0, 0 }, - { "filegroups", rd_filegroups, 0, 0 }, - { "mds_server_uuid", lprocfs_rd_server_uuid, 0, 0 }, - { "mds_conn_uuid", lprocfs_rd_conn_uuid, 0, 0 }, - { 0 } -}; - -struct lprocfs_vars lprocfs_module_vars[] = { - { "num_refs", lprocfs_rd_numrefs, 0, 0 }, - { 0 } -}; - -#endif /* LPROCFS */ - -LPROCFS_INIT_VARS(lprocfs_module_vars, lprocfs_obd_vars) diff --git a/lustre/mdc/mdc_reint.c b/lustre/mdc/mdc_reint.c deleted file mode 100644 index 3553a45..0000000 --- a/lustre/mdc/mdc_reint.c +++ /dev/null @@ -1,230 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2001-2003 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 - -/* mdc_setattr does its own semaphore handling */ -static int mdc_reint(struct ptlrpc_request *request, int level) -{ - int rc; - __u32 *opcodeptr = lustre_msg_buf(request->rq_reqmsg, 0); - - request->rq_level = level; - - if (!(*opcodeptr == REINT_SETATTR)) - mdc_get_rpc_lock(&mdc_rpc_lock, NULL); - rc = ptlrpc_queue_wait(request); - if (!(*opcodeptr == REINT_SETATTR)) - mdc_put_rpc_lock(&mdc_rpc_lock, NULL); - - if (rc) { - CDEBUG(D_INFO, "error in handling %d\n", rc); - } else { - /* For future resend/replays. */ - *opcodeptr |= REINT_REPLAYING; - } - return rc; -} - -/* If mdc_setattr is called with an 'iattr', then it is a normal RPC that - * should take the normal semaphore and go to the normal portal. - * - * If it is called with iattr->ia_valid & ATTR_FROM_OPEN, then it is a - * magic open-path setattr that should take the setattr semaphore and - * go to the setattr portal. */ -int mdc_setattr(struct lustre_handle *conn, struct inode *inode, - struct iattr *iattr, void *ea, int ealen, - struct ptlrpc_request **request) -{ - struct ptlrpc_request *req; - struct mds_rec_setattr *rec; - struct mdc_rpc_lock *rpc_lock; - int rc, bufcount = 1, size[2] = {sizeof(*rec), ealen}; - ENTRY; - - LASSERT(iattr != NULL); - - if (ealen > 0) - bufcount = 2; - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, bufcount, - size, NULL); - if (!req) - RETURN(-ENOMEM); - - if (iattr->ia_valid & ATTR_FROM_OPEN) { - req->rq_request_portal = MDS_SETATTR_PORTAL; //XXX FIXME bug 249 - rpc_lock = &mdc_setattr_lock; - } else - rpc_lock = &mdc_rpc_lock; - - mds_setattr_pack(req, inode, iattr, ea, ealen); - - size[0] = sizeof(struct mds_body); - req->rq_replen = lustre_msg_size(1, size); - - mdc_get_rpc_lock(rpc_lock, NULL); - rc = mdc_reint(req, LUSTRE_CONN_FULL); - mdc_put_rpc_lock(rpc_lock, NULL); - - *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; - } - - if (!rc) - 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 obd_device *obddev = class_conn2obd(conn); - struct ptlrpc_request *req = *request; - int rc, size[2] = {sizeof(struct mds_rec_unlink), namelen + 1}; - ENTRY; - - LASSERT(req == NULL); - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 2, size, - NULL); - if (!req) - RETURN(-ENOMEM); - *request = req; - - size[0] = sizeof(struct mds_body); - size[1] = obddev->u.cli.cl_max_mds_easize; - req->rq_replen = lustre_msg_size(2, size); - - mds_unlink_pack(req, 0, dir, child, mode, name, namelen); - - rc = mdc_reint(req, LUSTRE_CONN_FULL); - if (rc == -ERESTARTSYS) - rc = 0; - RETURN(rc); -} - -int mdc_link(struct lustre_handle *conn, - struct inode *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, 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 68075f5..0000000 --- a/lustre/mdc/mdc_request.c +++ /dev/null @@ -1,790 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2001-2003 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 -#include - -#define REQUEST_MINOR 244 - -extern int mds_queue_req(struct ptlrpc_request *); -struct mdc_rpc_lock mdc_rpc_lock; -struct mdc_rpc_lock mdc_setattr_lock; -EXPORT_SYMBOL(mdc_rpc_lock); - -/* Helper that implements most of mdc_getstatus and signal_completed_replay. */ -static int send_getstatus(struct obd_import *imp, struct ll_fid *rootfid, - int level, int msg_flags) -{ - struct ptlrpc_request *req; - struct mds_body *body; - int rc, size = sizeof(*body); - ENTRY; - - req = ptlrpc_prep_req(imp, MDS_GETSTATUS, 1, &size, NULL); - if (!req) - GOTO(out, rc = -ENOMEM); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - req->rq_level = level; - req->rq_replen = lustre_msg_size(1, &size); - - mds_pack_req_body(req); - req->rq_reqmsg->flags |= msg_flags; - mdc_get_rpc_lock(&mdc_rpc_lock, NULL); - rc = ptlrpc_queue_wait(req); - mdc_put_rpc_lock(&mdc_rpc_lock, NULL); - - 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; -} - -/* should become mdc_getinfo() */ -int mdc_getstatus(struct lustre_handle *conn, struct ll_fid *rootfid) -{ - return send_getstatus(class_conn2cliimp(conn), rootfid, LUSTRE_CONN_CON, - 0); -} - -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); - mdc_get_rpc_lock(&mdc_rpc_lock, NULL); - rc = ptlrpc_queue_wait(req); - mdc_put_rpc_lock(&mdc_rpc_lock, NULL); - - out: - RETURN(rc); -} - -int mdc_getattr(struct lustre_handle *conn, - obd_id ino, int type, unsigned long valid, unsigned int 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, "reserved %u bytes for MD/symlink in packet\n", - ea_size); - } - req->rq_replen = lustre_msg_size(bufcount, size); - mds_pack_req_body(req); - - mdc_get_rpc_lock(&mdc_rpc_lock, NULL); - rc = ptlrpc_queue_wait(req); - mdc_put_rpc_lock(&mdc_rpc_lock, NULL); - if (!rc) { - body = lustre_msg_buf(req->rq_repmsg, 0); - mds_unpack_body(body); - CDEBUG(D_NET, "mode: %o\n", body->mode); - } - - GOTO(out, rc); - out: - *request = req; - return rc; -} - -int mdc_getattr_name(struct lustre_handle *conn, struct inode *parent, - char *filename, int namelen, unsigned long valid, - unsigned int ea_size, struct ptlrpc_request **request) -{ - struct ptlrpc_request *req; - struct mds_body *body; - int rc, size[2] = {sizeof(*body), namelen}, bufcount = 1; - ENTRY; - - req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_GETATTR_NAME, 2, - size, NULL); - if (!req) - GOTO(out, rc = -ENOMEM); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - ll_inode2fid(&body->fid1, parent); - body->valid = valid; - memcpy(lustre_msg_buf(req->rq_reqmsg, 1), filename, namelen); - - if (ea_size) { - size[1] = ea_size; - bufcount++; - body->size = ea_size; - CDEBUG(D_INODE, "reserved %u bytes for MD/symlink in packet\n", - ea_size); - valid |= OBD_MD_FLEASIZE; - } - - req->rq_replen = lustre_msg_size(bufcount, size); - mds_pack_req_body(req); - - mdc_get_rpc_lock(&mdc_rpc_lock, NULL); - rc = ptlrpc_queue_wait(req); - mdc_put_rpc_lock(&mdc_rpc_lock, NULL); - if (!rc) { - body = lustre_msg_buf(req->rq_repmsg, 0); - mds_unpack_body(body); - } - - EXIT; - out: - *request = req; - return rc; -} - -/* 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); - - memcpy(&rec->cr_replayfid, &body->fid1, sizeof rec->cr_replayfid); - DEBUG_REQ(D_HA, req, "storing generation %x for ino "LPD64, - rec->cr_replayfid.generation, rec->cr_replayfid.id); -} - -static int mdc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, - void *data, 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 = lock->l_data; - - LASSERT(data != NULL); - - /* XXX what tells us that 'data' is a valid inode at all? - * we should probably validate the lock handle first? - */ - inode = igrab(inode); - - if (inode == NULL) /* inode->i_state & I_FREEING */ - break; - - if (S_ISDIR(inode->i_mode)) { - CDEBUG(D_INODE, "invalidating inode %lu\n", - inode->i_ino); - - ll_invalidate_inode_pages(inode); - } - - if (inode->i_sb->s_root && - inode != inode->i_sb->s_root->d_inode) - d_unhash_aliases(inode); - - iput(inode); - break; - } - default: - LBUG(); - } - - RETURN(0); -} - -/* We always reserve enough space in the reply packet for a stripe MD, because - * we don't know in advance the file type. - * - * XXX we could get that from ext2_dir_entry_2 file_type - */ -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); - struct ldlm_res_id res_id = - { .name = {dir->i_ino, 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 mdc_unlink_data *d = data; - struct ldlm_reply *dlm_rep; - struct ldlm_intent *lit; - struct ldlm_request *lockreq; - ENTRY; - - LDLM_DEBUG_NOLOCK("mdsintent %s parent dir %lu", - ldlm_it2str(it->it_op), dir->i_ino); - - if (it->it_op & IT_OPEN) { - it->it_mode |= S_IFREG; - it->it_mode &= ~current->fs->umask; - - size[2] = sizeof(struct mds_rec_create); - size[3] = de->d_name.len + 1; - req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 4, - size, NULL); - if (!req) - RETURN(-ENOMEM); - - req->rq_flags |= PTL_RPC_FL_REPLAY; - - /* pack the intent */ - lit = lustre_msg_buf(req->rq_reqmsg, 1); - lit->opc = NTOH__u64((__u64)it->it_op); - - /* pack the intended request */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - mds_open_pack(req, 2, dir, it->it_mode, 0, current->fsuid, - current->fsgid, CURRENT_TIME, it->it_flags, - de->d_name.name, de->d_name.len, tgt, tgtlen); -#else - mds_open_pack(req, 2, dir, it->it_mode, 0, current->fsuid, - current->fsgid, CURRENT_TIME.tv_sec, it->it_flags, - de->d_name.name, de->d_name.len, tgt, tgtlen); -#endif - req->rq_replen = lustre_msg_size(3, repsize); - } else if (it->it_op & IT_UNLINK) { - size[2] = sizeof(struct mds_rec_unlink); - size[3] = d->unl_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, d->unl_dir, - d->unl_de, d->unl_mode, - d->unl_name, d->unl_len); - req->rq_replen = lustre_msg_size(3, repsize); - } else if (it->it_op & (IT_GETATTR | IT_LOOKUP)) { - int valid = OBD_MD_FLNOTOBD | OBD_MD_FLEASIZE; - 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, valid, 2, it->it_flags, 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); - } - - mdc_get_rpc_lock(&mdc_rpc_lock, it); - 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, dir, NULL, - lockh); - mdc_put_rpc_lock(&mdc_rpc_lock, it); - - /* If we successfully created, mark the request so that replay will - * do the right thing */ - if (req->rq_transno) { - struct mds_rec_create *rec = lustre_msg_buf(req->rq_reqmsg, 2); - rec->cr_opcode |= REINT_REPLAYING; - } - /* Similarly, if we're going to replay this request, we don't want to - * actually get a lock, just perform the intent. */ - if (req->rq_transno || (req->rq_flags & PTL_RPC_FL_REPLAY)) { - lockreq = lustre_msg_buf(req->rq_reqmsg, 0); - lockreq->lock_flags |= LDLM_FL_INTENT_ONLY; - } - - /* This can go when we're sure that this can never happen */ - LASSERT(rc != -ENOENT); - if (rc == ELDLM_LOCK_ABORTED) { - lock_mode = 0; - memset(lockh, 0, sizeof(*lockh)); - } else if (rc != 0) { - CERROR("ldlm_cli_enqueue: %d\n", rc); - RETURN(rc); - } else { /* rc = 0 */ - struct ldlm_lock *lock = ldlm_handle2lock(lockh); - struct lustre_handle lockh2; - LASSERT(lock); - - /* If the server gave us back a different lock mode, we should - * fix up our variables. */ - if (lock->l_req_mode != lock_mode) { - ldlm_lock_addref(lockh, lock->l_req_mode); - ldlm_lock_decref(lockh, lock_mode); - lock_mode = lock->l_req_mode; - } - - /* 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. */ - LDLM_DEBUG(lock, "matching against this"); - - memcpy(&lockh2, lockh, sizeof(lockh2)); - if (ldlm_lock_match(NULL, LDLM_FL_BLOCK_GRANTED, NULL, - LDLM_PLAIN, NULL, 0, LCK_NL, &lockh2)) { - /* We already have a lock; cancel the new one */ - ldlm_lock_decref_and_cancel(lockh, lock_mode); - memcpy(lockh, &lockh2, sizeof(lockh2)); - } - LDLM_LOCK_PUT(lock); - } - - 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(rc); -} - -void mdc_lock_set_inode(struct lustre_handle *lockh, struct inode *inode) -{ - struct ldlm_lock *lock = ldlm_handle2lock(lockh); - ENTRY; - - LASSERT(lock != NULL); - lock->l_data = inode; - LDLM_LOCK_PUT(lock); - EXIT; -} - -int mdc_cancel_unused(struct lustre_handle *conn, struct inode *inode, - int flags) -{ - struct ldlm_res_id res_id = - { .name = {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)); -} - -static void mdc_replay_open(struct ptlrpc_request *req) -{ - struct lustre_handle old, *file_fh = req->rq_replay_data; - struct list_head *tmp; - struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 0); - - mds_unpack_body(body); - memcpy(&old, file_fh, sizeof(old)); - CDEBUG(D_HA, "updating from "LPD64"/"LPD64" to "LPD64"/"LPD64"\n", - file_fh->addr, file_fh->cookie, body->handle.addr, - body->handle.cookie); - memcpy(file_fh, &body->handle, sizeof(body->handle)); - - /* A few frames up, ptlrpc_replay holds the lock, so this is safe. */ - list_for_each(tmp, &req->rq_import->imp_sending_list) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - if (req->rq_reqmsg->opc != MDS_CLOSE) - continue; - body = lustre_msg_buf(req->rq_reqmsg, 0); - if (memcmp(&body->handle, &old, sizeof(old))) - continue; - - DEBUG_REQ(D_HA, req, "updating close body with new fh"); - memcpy(&body->handle, file_fh, sizeof(*file_fh)); - } -} - -void mdc_set_open_replay_data(struct ll_file_data *fd) -{ - struct ptlrpc_request *req = fd->fd_req; - struct mds_rec_create *rec = lustre_msg_buf(req->rq_reqmsg, 2); - struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 1); - - memcpy(&rec->cr_replayfid, &body->fid1, sizeof rec->cr_replayfid); - fd->fd_req->rq_replay_cb = mdc_replay_open; - fd->fd_req->rq_replay_data = &fd->fd_mdshandle; -} - -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); - - mdc_get_rpc_lock(&mdc_rpc_lock, NULL); - rc = ptlrpc_queue_wait(req); - mdc_put_rpc_lock(&mdc_rpc_lock, NULL); - - 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 obd_import *imp = class_conn2cliimp(conn); - 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(imp, MDS_READPAGE, 1, &size, NULL); - if (!req) - GOTO(out2, rc = -ENOMEM); - - /* XXX FIXME bug 249 */ - req->rq_request_portal = MDS_READPAGE_PORTAL; - - bulk = ptlrpc_prep_bulk_page(desc); - if (bulk == NULL) - GOTO(out2, rc = -ENOMEM); - - bulk->bp_xid = ptlrpc_next_xid(); - bulk->bp_buflen = PAGE_CACHE_SIZE; - bulk->bp_buf = addr; - - desc->bd_ptl_ev_hdlr = NULL; - desc->bd_portal = MDS_BULK_PORTAL; - - rc = ptlrpc_register_bulk_put(desc); - if (rc) { - CERROR("couldn't setup bulk sink: error %d.\n", rc); - GOTO(out2, rc); - } - - mds_readdir_pack(req, offset, ino, type, bulk->bp_xid); - - 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_bulk_decref(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); - - mdc_get_rpc_lock(&mdc_rpc_lock, NULL); - rc = ptlrpc_queue_wait(req); - mdc_put_rpc_lock(&mdc_rpc_lock, NULL); - - 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) -{ - struct lprocfs_static_vars lvars; - - lprocfs_init_vars(&lvars); - return lprocfs_obd_attach(dev, lvars.obd_vars); -} - -static int mdc_detach(struct obd_device *dev) -{ - return lprocfs_obd_detach(dev); -} - -/* Send a mostly-dummy GETSTATUS request and indicate that we're done replay. */ -static int signal_completed_replay(struct obd_import *imp) -{ - struct ll_fid fid; - - return send_getstatus(imp, &fid, LUSTRE_CONN_RECOVD, MSG_LAST_REPLAY); -} - -static int mdc_recover(struct obd_import *imp, int phase) -{ - int rc; - unsigned long flags; - struct ptlrpc_request *req; - struct ldlm_namespace *ns = imp->imp_obd->obd_namespace; - ENTRY; - - switch(phase) { - case PTLRPC_RECOVD_PHASE_PREPARE: - ldlm_cli_cancel_unused(ns, NULL, LDLM_FL_LOCAL_ONLY); - RETURN(0); - - case PTLRPC_RECOVD_PHASE_NOTCONN: - ldlm_namespace_cleanup(ns, 1); - ptlrpc_abort_inflight(imp, 0); - /* FALL THROUGH */ - case PTLRPC_RECOVD_PHASE_RECOVER: - reconnect: - rc = ptlrpc_reconnect_import(imp, MDS_CONNECT, &req); - - flags = req->rq_repmsg - ? lustre_msg_get_op_flags(req->rq_repmsg) - : 0; - - if (rc == -EBUSY && (flags & MSG_CONNECT_RECOVERING)) - CERROR("reconnect denied by recovery; should retry\n"); - - if (rc) { - if (phase != PTLRPC_RECOVD_PHASE_NOTCONN) { - CERROR("can't reconnect, invalidating\n"); - ldlm_namespace_cleanup(ns, 1); - ptlrpc_abort_inflight(imp, 0); - } - ptlrpc_req_finished(req); - RETURN(rc); - } - - if (flags & MSG_CONNECT_RECOVERING) { - /* Replay if they want it. */ - DEBUG_REQ(D_HA, req, "MDS wants replay"); - rc = ptlrpc_replay(imp); - if (rc) - GOTO(check_rc, rc); - - rc = ldlm_replay_locks(imp); - if (rc) - GOTO(check_rc, rc); - - rc = signal_completed_replay(imp); - if (rc) - GOTO(check_rc, rc); - } else if (flags & MSG_CONNECT_RECONNECT) { - DEBUG_REQ(D_HA, req, "reconnecting to MDS"); - /* Nothing else to do here. */ - } else { - DEBUG_REQ(D_HA, req, "evicted: invalidating"); - /* Otherwise, clean everything up. */ - ldlm_namespace_cleanup(ns, 1); - ptlrpc_abort_inflight(imp, 0); - } - - ptlrpc_req_finished(req); - spin_lock_irqsave(&imp->imp_lock, flags); - imp->imp_level = LUSTRE_CONN_FULL; - spin_unlock_irqrestore(&imp->imp_lock, flags); - - ptlrpc_wake_delayed(imp); - - rc = ptlrpc_resend(imp); - if (rc) - GOTO(check_rc, rc); - - RETURN(0); - check_rc: - /* If we get disconnected in the middle, recovery has probably - * failed. Reconnect and find out. - */ - if (rc == -ENOTCONN) - goto reconnect; - RETURN(rc); - - default: - RETURN(-EINVAL); - } -} - -static int mdc_connect(struct lustre_handle *conn, struct obd_device *obd, - struct obd_uuid *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_owner: THIS_MODULE, - 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) -{ - struct lprocfs_static_vars lvars; - mdc_init_rpc_lock(&mdc_rpc_lock); - mdc_init_rpc_lock(&mdc_setattr_lock); - lprocfs_init_vars(&lvars); - return class_register_type(&mdc_obd_ops, lvars.module_vars, - LUSTRE_MDC_NAME); -} - -static void __exit ptlrpc_request_exit(void) -{ - class_unregister_type(LUSTRE_MDC_NAME); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Metadata Client"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(mdc_getstatus); -EXPORT_SYMBOL(mdc_getlovinfo); -EXPORT_SYMBOL(mdc_enqueue); -EXPORT_SYMBOL(mdc_cancel_unused); -EXPORT_SYMBOL(mdc_getattr); -EXPORT_SYMBOL(mdc_getattr_name); -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_lock_set_inode); -EXPORT_SYMBOL(mdc_set_open_replay_data); - -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 f789c22..0000000 --- a/lustre/mds/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 = mds - -modulefs_DATA = mds.o -EXTRA_PROGRAMS = mds - -LINX= mds_updates.c mds_open.c simple.c target.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 58cfa20..0000000 --- a/lustre/mds/handler.c +++ /dev/null @@ -1,1857 +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-2003 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 -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#include -#include -#include -#else -#include -#endif -#include -#include -#include -#include - -kmem_cache_t *mds_file_cache; - -extern int mds_get_lovtgts(struct mds_obd *obd, int tgt_count, - struct obd_uuid *uuidarray); -extern int mds_get_lovdesc(struct mds_obd *obd, struct lov_desc *desc); -int mds_finish_transno(struct mds_obd *mds, struct inode *i, void *handle, - struct ptlrpc_request *req, int rc, int disp); -static int mds_cleanup(struct obd_device * obddev); - -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, __u64 xid) -{ - struct ptlrpc_bulk_desc *desc; - struct ptlrpc_bulk_page *bulk; - struct l_wait_info lwi; - char *buf; - int rc = 0; - 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_CACHE_SIZE); - if (buf == NULL) - GOTO(cleanup_bulk, rc = -ENOMEM); - - CDEBUG(D_EXT2, "reading %lu@"LPU64" from dir %lu (size %llu)\n", - PAGE_CACHE_SIZE, offset, file->f_dentry->d_inode->i_ino, - file->f_dentry->d_inode->i_size); - rc = fsfilt_readpage(req->rq_export->exp_obd, file, buf, - PAGE_CACHE_SIZE, (loff_t *)&offset); - - if (rc != PAGE_CACHE_SIZE) - GOTO(cleanup_buf, rc = -EIO); - - bulk->bp_xid = xid; - bulk->bp_buf = buf; - bulk->bp_buflen = PAGE_CACHE_SIZE; - desc->bd_ptl_ev_hdlr = NULL; - desc->bd_portal = MDS_BULK_PORTAL; - - rc = ptlrpc_bulk_put(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_bulk_decref(desc); - out: - return rc; -} - -/* only valid locked dentries or errors should be returned */ -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; - struct ldlm_res_id res_id = { .name = {0} }; - int flags = 0, rc; - ENTRY; - - if (IS_ERR(de)) - RETURN(de); - - res_id.name[0] = de->d_inode->i_ino; - res_id.name[1] = de->d_inode->i_generation; - 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, NULL, 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. */ -/* this function ONLY returns valid dget'd dentries with an initialized inode - or errors */ -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, - struct obd_uuid *cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct obd_export *exp; - struct mds_export_data *med; - struct mds_client_data *mcd; - int rc; - ENTRY; - - if (!conn || !obd || !cluuid) - RETURN(-EINVAL); - - /* Check for aborted recovery. */ - spin_lock_bh(&obd->obd_processing_task_lock); - if (obd->obd_flags & OBD_ABORT_RECOVERY) - target_abort_recovery(obd); - spin_unlock_bh(&obd->obd_processing_task_lock); - - /* 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) - RETURN(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); - - 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; - int rc; - struct dentry *de = NULL; - LASSERT(file->private_data == mfd); - - LASSERT(mfd->mfd_servercookie != DEAD_HANDLE_MAGIC); - - list_del(&mfd->mfd_list); - mfd->mfd_servercookie = DEAD_HANDLE_MAGIC; - kmem_cache_free(mds_file_cache, mfd); - - if (file->f_dentry->d_parent) { - LASSERT(atomic_read(&file->f_dentry->d_parent->d_count)); - de = dget(file->f_dentry->d_parent); - } - rc = filp_close(file, 0); - if (de) - l_dput(de); - RETURN(rc); -} - -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); - CERROR("force closing client file handle for %*s\n", - mfd->mfd_file->f_dentry->d_name.len, - mfd->mfd_file->f_dentry->d_name.name); - rc = mds_close_mfd(mfd, med); - if (rc) - CDEBUG(D_INODE, "Error closing file: %d\n", rc); - } - spin_unlock(&med->med_open_lock); - - ldlm_cancel_locks_for_export(export); - if (med->med_outstanding_reply) { - /* Fake the ack, so the locks get cancelled. */ - med->med_outstanding_reply->rq_flags &= ~PTL_RPC_FL_WANT_ACK; - med->med_outstanding_reply->rq_flags |= PTL_RPC_FL_ERR; - wake_up(&med->med_outstanding_reply->rq_wait_for_rep); - med->med_outstanding_reply = NULL; - } - mds_client_free(export); - - rc = class_disconnect(conn); - - 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(-ENOMEM); - } - - /* 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(-ENOMEM); - } - - if (!mds->mds_has_lov_desc) { - req->rq_status = -ENOENT; - RETURN(0); - } - - desc = lustre_msg_buf(req->rq_repmsg, 0); - memcpy(desc, &mds->mds_lov_desc, sizeof *desc); - lov_packdesc(desc); - tgt_count = le32_to_cpu(desc->ld_tgt_count); - if (tgt_count * sizeof(struct obd_uuid) > streq->repbuf) { - CERROR("too many targets, enlarge client buffers\n"); - req->rq_status = -ENOSPC; - RETURN(0); - } - - 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, 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); - /* Get this: if mds_blocking_ast is racing with ldlm_intent_policy, - * such that mds_blocking_ast is called just before l_i_p takes the - * ns_lock, then by the time we get the lock, we might not be the - * correct blocking function anymore. So check, and return early, if - * so. */ - if (lock->l_blocking_ast != mds_blocking_ast) { - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - RETURN(0); - } - - 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 obd_device *obd, struct lustre_msg *msg, - int offset, struct mds_body *body, struct inode *inode) -{ - struct mds_obd *mds = &obd->u.mds; - struct lov_mds_md *lmm; - int lmm_size = msg->buflens[offset]; - int rc; - ENTRY; - - if (lmm_size == 0) { - CDEBUG(D_INFO, "no space reserved for inode %lu MD\n", - inode->i_ino); - RETURN(0); - } - - lmm = lustre_msg_buf(msg, 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 %lu 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 = fsfilt_get_md(obd, inode, lmm, lmm_size)) < 0) { - CDEBUG(D_INFO, "No md for ino %lu: 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 obd_device *obd, 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) && reqbody->valid & OBD_MD_FLEASIZE) { - rc = mds_pack_md(obd, req->rq_repmsg, 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; - rc = 0; - } - } - RETURN(rc); -} - -static int mds_getattr_pack_msg(struct ptlrpc_request *req, struct inode *inode, - int offset) -{ - struct mds_obd *mds = mds_req2mds(req); - struct mds_body *body; - int rc = 0, size[2] = {sizeof(*body)}, bufcount = 1; - ENTRY; - - body = lustre_msg_buf(req->rq_reqmsg, offset); - - if (S_ISREG(inode->i_mode) && body->valid & OBD_MD_FLEASIZE) { - int rc = fsfilt_get_md(req->rq_export->exp_obd, inode, NULL, 0); - CDEBUG(D_INODE, "got %d bytes MD data for inode %lu\n", - rc, inode->i_ino); - if (rc < 0) { - if (rc != -ENODATA) - CERROR("error getting inode %lu 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: %Lu, reply space: "LPU64"\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); - } - - EXIT; - out: - return(rc); -} - -/* This is more copy-and-paste from getattr_name than I'd like. */ -static void reconstruct_getattr_name(int offset, struct ptlrpc_request *req, - struct lustre_handle *client_lockh) -{ - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_client_data *mcd = med->med_mcd; - struct obd_device *obd = req->rq_export->exp_obd; - struct mds_obd *mds = mds_req2mds(req); - struct dentry *parent, *child; - struct mds_body *body; - struct inode *dir; - struct obd_run_ctxt saved; - struct obd_ucred uc; - int namelen, rc = 0; - char *name; - - req->rq_transno = mcd->mcd_last_transno; - req->rq_status = mcd->mcd_last_result; - - if (med->med_outstanding_reply) - mds_steal_ack_locks(med, req); - - if (req->rq_status) - return; - - 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; - uc.ouc_suppgid1 = body->suppgid; - uc.ouc_suppgid2 = -1; - push_ctxt(&saved, &mds->mds_ctxt, &uc); - parent = mds_fid2dentry(mds, &body->fid1, NULL); - LASSERT(!IS_ERR(parent)); - dir = parent->d_inode; - LASSERT(dir); - child = lookup_one_len(name, parent, namelen - 1); - LASSERT(!IS_ERR(child)); - - if (!med->med_outstanding_reply) { - /* XXX need to enqueue client lock */ - LBUG(); - } - - if (req->rq_repmsg == NULL) - mds_getattr_pack_msg(req, child->d_inode, offset); - - rc = mds_getattr_internal(obd, child, req, body, offset); - LASSERT(!rc); - l_dput(child); - l_dput(parent); -} - -static int mds_getattr_name(int offset, struct ptlrpc_request *req, - struct lustre_handle *child_lockh) -{ - struct mds_obd *mds = mds_req2mds(req); - struct obd_device *obd = req->rq_export->exp_obd; - struct obd_run_ctxt saved; - struct mds_body *body; - struct dentry *de = NULL, *dchild = NULL; - struct inode *dir; - struct obd_ucred uc; - struct ldlm_res_id child_res_id = { .name = {0} }; - struct lustre_handle parent_lockh; - int namelen, flags = 0, rc = 0, cleanup_phase = 0; - char *name; - ENTRY; - - LASSERT(!strcmp(obd->obd_type->typ_name, "mds")); - - MDS_CHECK_RESENT(req, - reconstruct_getattr_name(offset, req, child_lockh)); - - if (req->rq_reqmsg->bufcount <= offset + 1) { - LBUG(); - GOTO(cleanup, 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; - uc.ouc_suppgid1 = body->suppgid; - uc.ouc_suppgid2 = -1; - push_ctxt(&saved, &mds->mds_ctxt, &uc); - /* Step 1: Lookup/lock parent */ - de = mds_fid2locked_dentry(obd, &body->fid1, NULL, LCK_PR, - &parent_lockh); - if (IS_ERR(de)) - GOTO(cleanup, rc = PTR_ERR(de)); - dir = de->d_inode; - LASSERT(dir); - - cleanup_phase = 1; /* parent dentry and lock */ - - CDEBUG(D_INODE, "parent ino %lu, name %*s\n", dir->i_ino,namelen,name); - - /* Step 2: Lookup child */ - dchild = lookup_one_len(name, de, namelen - 1); - if (IS_ERR(dchild)) { - CDEBUG(D_INODE, "child lookup error %ld\n", PTR_ERR(dchild)); - GOTO(cleanup, rc = PTR_ERR(dchild)); - } - - cleanup_phase = 2; /* child dentry */ - - if (dchild->d_inode == NULL) { - GOTO(cleanup, rc = -ENOENT); - } - - /* Step 3: Lock child */ - child_res_id.name[0] = dchild->d_inode->i_ino; - child_res_id.name[1] = dchild->d_inode->i_generation; - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, - child_res_id, LDLM_PLAIN, NULL, 0, LCK_PR, - &flags, ldlm_completion_ast, mds_blocking_ast, - NULL, NULL, child_lockh); - if (rc != ELDLM_OK) { - CERROR("ldlm_cli_enqueue: %d\n", rc); - GOTO(cleanup, rc = -EIO); - } - - cleanup_phase = 3; /* child lock */ - - if (req->rq_repmsg == NULL) - mds_getattr_pack_msg(req, dchild->d_inode, offset); - - rc = mds_getattr_internal(obd, dchild, req, body, offset); - GOTO(cleanup, rc); /* returns the lock to the client */ - - cleanup: - rc = mds_finish_transno(mds, dchild ? dchild->d_inode : NULL, NULL, - req, rc, 0); - switch (cleanup_phase) { - case 3: - if (rc) - ldlm_lock_decref(child_lockh, LCK_PR); - case 2: - l_dput(dchild); - - case 1: - if (rc) { - ldlm_lock_decref(&parent_lockh, LCK_PR); - } else { - memcpy(&req->rq_ack_locks[0].lock, &parent_lockh, - sizeof(parent_lockh)); - req->rq_ack_locks[0].mode = LCK_PR; - } - l_dput(de); - default: ; - } - req->rq_status = rc; - pop_ctxt(&saved, &mds->mds_ctxt, &uc); - return rc; -} - -static int mds_getattr(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 dentry *de; - struct mds_body *body; - struct obd_ucred uc; - int rc = 0; - 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)); - } - - rc = mds_getattr_pack_msg(req, de->d_inode, offset); - - req->rq_status = mds_getattr_internal(obd, de, req, body, 0); - - l_dput(de); - GOTO(out_pop, rc); -out_pop: - pop_ctxt(&saved, &mds->mds_ctxt, &uc); - return rc; -} - -static int mds_statfs(struct ptlrpc_request *req) -{ - struct obd_device *obd = req->rq_export->exp_obd; - 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 || OBD_FAIL_CHECK(OBD_FAIL_MDS_STATFS_PACK)) { - CERROR("mds: statfs lustre_pack_msg failed: rc = %d\n", rc); - GOTO(out, rc); - } - - osfs = lustre_msg_buf(req->rq_repmsg, 0); - rc = fsfilt_statfs(obd, obd->u.mds.mds_sb, osfs); - if (rc) { - CERROR("mds: statfs failed: rc %d\n", rc); - GOTO(out, rc); - } - obd_statfs_pack(osfs, osfs); - - EXIT; -out: - req->rq_status = rc; - return 0; -} - -static struct mds_file_data *mds_handle2mfd(struct lustre_handle *handle) -{ - struct mds_file_data *mfd = NULL; - ENTRY; - - 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); -} - -#if 0 - -static int mds_store_md(struct mds_obd *mds, struct ptlrpc_request *req, - int offset, struct mds_body *body, struct inode *inode) -{ - struct obd_device *obd = req->rq_export->exp_obd; - 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 %lu 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 %lu\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); - handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR); - if (IS_ERR(handle)) { - rc = PTR_ERR(handle); - GOTO(out_ea, rc); - } - - rc = fsfilt_set_md(obd, inode,handle,lmm,lmm_size); - rc = mds_finish_transno(mds, inode, handle, req, rc, 0); -out_ea: - pop_ctxt(&saved, &mds->mds_ctxt, &uc); - - RETURN(rc); -} - -#endif - -static void reconstruct_close(struct ptlrpc_request *req) -{ - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_client_data *mcd = med->med_mcd; - - req->rq_transno = mcd->mcd_last_transno; - req->rq_status = mcd->mcd_last_result; - - /* XXX When open-unlink is working, we'll need to steal ack locks as - * XXX well, and make sure that we do the right unlinking after we - * XXX get the ack back. - */ -} - -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; - - MDS_CHECK_RESENT(req, reconstruct_close(req)); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - - mfd = mds_handle2mfd(&body->handle); - if (mfd == NULL) { - DEBUG_REQ(D_ERROR, req, "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 %lu\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 */ - /* body->blocks is actually the xid -phil */ - rc = mds_sendpage(req, file, body->size, body->blocks); - - 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, - struct lustre_handle *lockh) -{ - struct mds_update_record *rec; /* 116 bytes on the stack? no sir! */ - int rc; - - OBD_ALLOC(rec, sizeof(*rec)); - if (rec == NULL) - RETURN(-ENOMEM); - - rc = mds_update_unpack(req, offset, rec); - if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_UNPACK)) { - CERROR("invalid record\n"); - GOTO(out, req->rq_status = -EINVAL); - } - /* rc will be used to interrupt a for loop over multiple records */ - rc = mds_reint_rec(rec, offset, req, lockh); - out: - OBD_FREE(rec, sizeof(*rec)); - return rc; -} - -static int filter_recovery_request(struct ptlrpc_request *req, - struct obd_device *obd, int *process) -{ - switch (req->rq_reqmsg->opc) { - case MDS_CONNECT: /* This will never get here, but for completeness. */ - case MDS_DISCONNECT: - *process = 1; - RETURN(0); - - case MDS_CLOSE: - case MDS_GETSTATUS: /* used in unmounting */ - case MDS_REINT: - case LDLM_ENQUEUE: - *process = target_queue_recovery_request(req, obd); - RETURN(0); - - default: - DEBUG_REQ(D_ERROR, req, "not permitted during recovery"); - *process = 0; - /* XXX what should we set rq_status to here? */ - RETURN(ptlrpc_error(req->rq_svc, req)); - } -} - -static char *reint_names[] = { - [REINT_SETATTR] "setattr", - [REINT_CREATE] "create", - [REINT_LINK] "link", - [REINT_UNLINK] "unlink", - [REINT_RENAME] "rename", - [REINT_OPEN] "open", -}; - -void mds_steal_ack_locks(struct mds_export_data *med, - struct ptlrpc_request *req) -{ - struct ptlrpc_request *oldrep = med->med_outstanding_reply; - memcpy(req->rq_ack_locks, oldrep->rq_ack_locks, - sizeof req->rq_ack_locks); - oldrep->rq_flags |= PTL_RPC_FL_RESENT; - wake_up(&oldrep->rq_wait_for_rep); - DEBUG_REQ(D_HA, oldrep, "stole locks from"); - DEBUG_REQ(D_HA, req, "stole locks for"); -} - -static void mds_send_reply(struct ptlrpc_request *req, int rc) -{ - int i; - struct ptlrpc_req_ack_lock *ack_lock; - struct l_wait_info lwi; - struct mds_export_data *med = - (req->rq_export && req->rq_ack_locks[0].mode) ? - &req->rq_export->exp_mds_data : NULL; - - if (med) { - med->med_outstanding_reply = req; - req->rq_flags |= PTL_RPC_FL_WANT_ACK; - init_waitqueue_head(&req->rq_wait_for_rep); - } - - if (!OBD_FAIL_CHECK(OBD_FAIL_MDS_ALL_REPLY_NET | OBD_FAIL_ONCE)) { - if (rc) { - DEBUG_REQ(D_ERROR, req, "processing error (%d)", rc); - ptlrpc_error(req->rq_svc, req); - } else { - DEBUG_REQ(D_NET, req, "sending reply"); - ptlrpc_reply(req->rq_svc, req); - } - } else { - obd_fail_loc |= OBD_FAIL_ONCE | OBD_FAILED; - DEBUG_REQ(D_ERROR, req, "dropping reply"); - if (!med && req->rq_repmsg) - OBD_FREE(req->rq_repmsg, req->rq_replen); - } - - if (!med) { - DEBUG_REQ(D_HA, req, "not waiting for ack"); - return; - } - - lwi = LWI_TIMEOUT(obd_timeout / 2 * HZ, NULL, NULL); - rc = l_wait_event(req->rq_wait_for_rep, - (req->rq_flags & PTL_RPC_FL_WANT_ACK) == 0 || - (req->rq_flags & PTL_RPC_FL_RESENT), - &lwi); - - if (req->rq_flags & PTL_RPC_FL_RESENT) { - /* The client resent this request, so abort the - * waiting-ack portals stuff, and don't decref the - * locks. - */ - DEBUG_REQ(D_HA, req, "resent: not cancelling locks"); - ptlrpc_abort(req); - return; - } - - if (rc == -ETIMEDOUT) { - ptlrpc_abort(req); - recovd_conn_fail(req->rq_export->exp_connection); - DEBUG_REQ(D_HA, req, "cancelling locks for timeout"); - } else { - DEBUG_REQ(D_HA, req, "cancelling locks for ack"); - } - - med->med_outstanding_reply = NULL; - - for (ack_lock = req->rq_ack_locks, i = 0; i < 4; i++, ack_lock++) { - if (!ack_lock->mode) - break; - ldlm_lock_decref(&ack_lock->lock, ack_lock->mode); - } -} - -int mds_handle(struct ptlrpc_request *req) -{ - int should_process, rc; - struct mds_obd *mds = NULL; /* quell gcc overwarning */ - struct obd_device *obd = NULL; - ENTRY; - - rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); - if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_HANDLE_UNPACK)) { - DEBUG_REQ(D_ERROR, req, "invalid request (%d)", rc); - GOTO(out, rc); - } - - OBD_FAIL_RETURN(OBD_FAIL_MDS_ALL_REQUEST_NET | OBD_FAIL_ONCE, 0); - - LASSERT(!strcmp(req->rq_obd->obd_type->typ_name, LUSTRE_MDT_NAME)); - - if (req->rq_reqmsg->opc != MDS_CONNECT) { - struct mds_export_data *med; - if (req->rq_export == NULL) { - req->rq_status = -ENOTCONN; - GOTO(out, rc = -ENOTCONN); - } - - med = &req->rq_export->exp_mds_data; - obd = req->rq_export->exp_obd; - mds = &obd->u.mds; - spin_lock_bh(&obd->obd_processing_task_lock); - if (obd->obd_flags & OBD_ABORT_RECOVERY) - target_abort_recovery(obd); - spin_unlock_bh(&obd->obd_processing_task_lock); - - if (obd->obd_flags & OBD_RECOVERING) { - rc = filter_recovery_request(req, obd, &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, mds_handle); - /* 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); - req->rq_status = rc; - break; - - 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_GETATTR_NAME: { - struct lustre_handle lockh; - DEBUG_REQ(D_INODE, req, "getattr_name"); - OBD_FAIL_RETURN(OBD_FAIL_MDS_GETATTR_NAME_NET, 0); - - /* If this request gets a reconstructed reply, we won't be - * acquiring any new locks in mds_getattr_name, so we don't - * want to cancel. - */ - lockh.addr = 0; - rc = mds_getattr_name(0, req, &lockh); - if (rc == 0 && lockh.addr) - ldlm_lock_decref(&lockh, LCK_PR); - 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"); - 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 opc = *(u32 *)lustre_msg_buf(req->rq_reqmsg, 0); - int size[2] = {sizeof(struct mds_body), mds->mds_max_mdsize}; - int bufcount; - - DEBUG_REQ(D_INODE, req, "reint (%s%s)", - reint_names[opc & REINT_OPCODE_MASK], - opc & REINT_REPLAYING ? "|REPLAYING" : ""); - - OBD_FAIL_RETURN(OBD_FAIL_MDS_REINT_NET, 0); - - if (opc == REINT_UNLINK) - bufcount = 2; - else - bufcount = 1; - - rc = lustre_pack_msg(bufcount, size, NULL, - &req->rq_replen, &req->rq_repmsg); - if (rc) - break; - - rc = mds_reint(req, 0, NULL); - OBD_FAIL_RETURN(OBD_FAIL_MDS_REINT_NET_REP, 0); - 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, ldlm_server_completion_ast, - ldlm_server_blocking_ast); - 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 we're DISCONNECTing, the mds_export_data is already freed */ - if (!rc && req->rq_reqmsg->opc != MDS_DISCONNECT) { - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct obd_device *obd = list_entry(mds, struct obd_device, - u.mds); - req->rq_repmsg->last_xid = - HTON__u64(le64_to_cpu(med->med_mcd->mcd_last_xid)); - if ((obd->obd_flags & OBD_NO_TRANSNO) == 0) { - req->rq_repmsg->last_committed = - HTON__u64(obd->obd_last_committed); - } else { - DEBUG_REQ(D_IOCTL, req, - "not sending last_committed update"); - } - CDEBUG(D_INFO, "last_transno "LPU64", last_committed "LPU64 - ", xid "LPU64"\n", - mds->mds_last_transno, obd->obd_last_committed, - NTOH__u64(req->rq_xid)); - } - out: - - if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_LAST_REPLAY) { - if (obd && (obd->obd_flags & OBD_RECOVERING)) { - DEBUG_REQ(D_HA, req, "LAST_REPLAY, queuing reply"); - return target_queue_final_reply(req, rc); - } - /* Lost a race with recovery; let the error path DTRT. */ - rc = req->rq_status = -ENOTCONN; - } - - mds_send_reply(req, rc); - 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. - * - * Also assumes for mds_last_transno 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; - struct obd_run_ctxt saved; - loff_t off = 0; - int rc; - - push_ctxt(&saved, &mds->mds_ctxt, NULL); - msd->msd_last_transno = cpu_to_le64(mds->mds_last_transno); - msd->msd_mount_count = cpu_to_le64(mds->mds_mount_count); - - CDEBUG(D_SUPER, "MDS mount_count is %Lu, last_transno is %Lu\n", - (unsigned long long)mds->mds_mount_count, - (unsigned long long)mds->mds_last_transno); - 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) - rc = -EIO; - GOTO(out, 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); - -out: - 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; - -#ifdef CONFIG_DEV_RDONLY - dev_clear_rdonly(2); -#endif - if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2) - RETURN(rc = -EINVAL); - - obddev->obd_fsops = fsfilt_get_ops(data->ioc_inlbuf2); - if (IS_ERR(obddev->obd_fsops)) - RETURN(rc = PTR_ERR(obddev->obd_fsops)); - - mnt = do_kern_mount(data->ioc_inlbuf2, 0, data->ioc_inlbuf1, NULL); - if (IS_ERR(mnt)) { - rc = PTR_ERR(mnt); - CERROR("do_kern_mount failed: rc = %d\n", rc); - GOTO(err_ops, rc); - } - - CDEBUG(D_SUPER, "%s: mnt = %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); - - spin_lock_init(&mds->mds_transno_lock); - 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); - - mds->mds_has_lov_desc = 0; - - RETURN(0); - -err_fs: - mds_fs_cleanup(obddev); -err_put: - unlock_kernel(); - mntput(mds->mds_vfsmnt); - mds->mds_sb = 0; - lock_kernel(); -err_ops: - fsfilt_put_ops(obddev->obd_fsops); - return rc; -} - -static int mds_cleanup(struct obd_device *obddev) -{ - struct super_block *sb; - struct mds_obd *mds = &obddev->u.mds; - ENTRY; - - sb = mds->mds_sb; - if (!mds->mds_sb) - RETURN(0); - - mds_update_server_data(mds); - mds_fs_cleanup(obddev); - - unlock_kernel(); - mntput(mds->mds_vfsmnt); - mds->mds_sb = 0; - - ldlm_namespace_free(obddev->obd_namespace); - - lock_kernel(); -#ifdef CONFIG_DEV_RDONLY - dev_clear_rdonly(2); -#endif - fsfilt_put_ops(obddev->obd_fsops); - - RETURN(0); -} - -inline void fixup_handle_for_resent_req(struct ptlrpc_request *req, - struct lustre_handle *lockh) -{ - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_client_data *mcd = med->med_mcd; - struct ptlrpc_request *oldrep = med->med_outstanding_reply; - struct ldlm_reply *dlm_rep; - - if ((lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) && - (mcd->mcd_last_xid == req->rq_xid) && (oldrep != NULL)) { - DEBUG_REQ(D_HA, req, "restoring lock handle from %p", oldrep); - dlm_rep = lustre_msg_buf(oldrep->rq_repmsg, 0); - lockh->addr = dlm_rep->lock_handle.addr; - lockh->cookie = dlm_rep->lock_handle.cookie; - } -} - -static int ldlm_intent_policy(struct ldlm_namespace *ns, - struct ldlm_lock **lockp, void *req_cookie, - ldlm_mode_t mode, int flags, void *data) -{ - struct ptlrpc_request *req = req_cookie; - struct ldlm_lock *lock = *lockp; - 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_body; - struct ldlm_reply *rep; - struct lustre_handle lockh; - struct ldlm_lock *new_lock; - int rc, offset = 2, repsize[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, repsize, 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 = IT_INTENT_EXEC; - - fixup_handle_for_resent_req(req, &lockh); - - /* execute policy */ - switch ((long)it->opc) { - case IT_OPEN: - case IT_CREAT|IT_OPEN: - rc = mds_reint(req, offset, &lockh); - /* We return a dentry to the client if IT_OPEN_POS is - * set, or if we make it to the OPEN portion of the - * programme (which implies that we created) */ - if (!(rep->lock_policy_res1 & IT_OPEN_POS || - rep->lock_policy_res1 & IT_OPEN_OPEN)) { - rep->lock_policy_res2 = rc; - RETURN(ELDLM_LOCK_ABORTED); - } - break; - case IT_UNLINK: - rc = mds_reint(req, offset, &lockh); - /* Don't return a lock if the unlink failed, or if we're - * not sending back an EA */ - if (rc) { - rep->lock_policy_res2 = rc; - RETURN(ELDLM_LOCK_ABORTED); - } - if (req->rq_status != 0) { - rep->lock_policy_res2 = req->rq_status; - RETURN(ELDLM_LOCK_ABORTED); - } - mds_body = lustre_msg_buf(req->rq_repmsg, 1); - if (!(mds_body->valid & OBD_MD_FLEASIZE)) { - rep->lock_policy_res2 = rc; - RETURN(ELDLM_LOCK_ABORTED); - } - break; - case IT_GETATTR: - case IT_LOOKUP: - case IT_READDIR: - rc = mds_getattr_name(offset, req, &lockh); - /* 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) { - rep->lock_policy_res2 = rc; - RETURN(ELDLM_LOCK_ABORTED); - } - if (req->rq_status != 0) { - rep->lock_policy_res2 = req->rq_status; - RETURN(ELDLM_LOCK_ABORTED); - } - break; - default: - CERROR("Unhandled intent "LPD64"\n", it->opc); - LBUG(); - } - - if (flags & LDLM_FL_INTENT_ONLY) { - LDLM_DEBUG(lock, "INTENT_ONLY, aborting lock"); - RETURN(ELDLM_LOCK_ABORTED); - } - - /* By this point, whatever function we called above must have - * filled in 'lockh' or returned an error. We want to give the - * new lock to the client instead of whatever lock it was about - * to get. */ - new_lock = ldlm_handle2lock(&lockh); - LASSERT(new_lock != NULL); - *lockp = new_lock; - - rep->lock_policy_res2 = req->rq_status; - - if (new_lock->l_export == req->rq_export) { - /* Already gave this to the client, which means that we - * reconstructed a reply. */ - LASSERT(lustre_msg_get_flags(req->rq_reqmsg) & - MSG_RESENT); - RETURN(ELDLM_LOCK_REPLACED); - } - - /* Fixup the lock to be given to the client */ - l_lock(&new_lock->l_resource->lr_namespace->ns_lock); - LASSERT(new_lock->l_readers + new_lock->l_writers == 1); - new_lock->l_readers = 0; - new_lock->l_writers = 0; - - new_lock->l_export = req->rq_export; - list_add(&new_lock->l_export_chain, - &new_lock->l_export->exp_ldlm_data.led_held_locks); - - /* We don't need to worry about completion_ast (which isn't set - * in 'lock' yet anyways), because this lock is already - * granted. */ - new_lock->l_blocking_ast = lock->l_blocking_ast; - - memcpy(&new_lock->l_remote_handle, &lock->l_remote_handle, - sizeof(lock->l_remote_handle)); - - new_lock->l_flags &= ~(LDLM_FL_LOCAL | LDLM_FL_AST_SENT | - LDLM_FL_CBPENDING); - - LDLM_LOCK_PUT(new_lock); - l_unlock(&new_lock->l_resource->lr_namespace->ns_lock); - - RETURN(ELDLM_LOCK_REPLACED); - } 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) -{ - struct lprocfs_static_vars lvars; - - lprocfs_init_multi_vars(0, &lvars); - return lprocfs_obd_attach(dev, lvars.obd_vars); -} - -int mds_detach(struct obd_device *dev) -{ - return lprocfs_obd_detach(dev); -} - -int mdt_attach(struct obd_device *dev, obd_count len, void *data) -{ - struct lprocfs_static_vars lvars; - - lprocfs_init_multi_vars(1, &lvars); - return lprocfs_obd_attach(dev, lvars.obd_vars); -} - -int mdt_detach(struct obd_device *dev) -{ - return lprocfs_obd_detach(dev); -} - -static int mdt_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - struct mds_obd *mds = &obddev->u.mds; - int i, rc = 0; - ENTRY; - - mds->mds_service = ptlrpc_init_svc(MDS_NEVENTS, MDS_NBUFS, - MDS_BUFSIZE, MDS_MAXREQSIZE, - MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL, - mds_handle, "mds"); - if (!mds->mds_service) { - CERROR("failed to start service\n"); - RETURN(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); - } - } - - mds->mds_setattr_service = - ptlrpc_init_svc(MDS_NEVENTS, MDS_NBUFS, - MDS_BUFSIZE, MDS_MAXREQSIZE, - MDS_SETATTR_PORTAL, MDC_REPLY_PORTAL, - mds_handle, "mds"); - if (!mds->mds_setattr_service) { - CERROR("failed to start getattr service\n"); - GOTO(err_thread, rc = -ENOMEM); - } - - for (i = 0; i < MDT_NUM_THREADS; i++) { - char name[32]; - sprintf(name, "ll_mdt_attr_%02d", i); - rc = ptlrpc_start_thread(obddev, mds->mds_setattr_service, - name); - if (rc) { - CERROR("cannot start MDT setattr thread #%d: rc %d\n", - i, rc); - GOTO(err_thread2, rc); - } - } - - mds->mds_readpage_service = - ptlrpc_init_svc(MDS_NEVENTS, MDS_NBUFS, - MDS_BUFSIZE, MDS_MAXREQSIZE, - MDS_READPAGE_PORTAL, MDC_REPLY_PORTAL, - mds_handle, "mds"); - if (!mds->mds_readpage_service) { - CERROR("failed to start readpage service\n"); - GOTO(err_thread2, rc = -ENOMEM); - } - - for (i = 0; i < MDT_NUM_THREADS; i++) { - char name[32]; - sprintf(name, "ll_mdt_rdpg_%02d", i); - rc = ptlrpc_start_thread(obddev, mds->mds_readpage_service, - name); - if (rc) { - CERROR("cannot start MDT readpage thread #%d: rc %d\n", - i, rc); - GOTO(err_thread3, rc); - } - } - - RETURN(0); - -err_thread3: - ptlrpc_stop_all_threads(mds->mds_readpage_service); - ptlrpc_unregister_service(mds->mds_readpage_service); -err_thread2: - ptlrpc_stop_all_threads(mds->mds_setattr_service); - ptlrpc_unregister_service(mds->mds_setattr_service); -err_thread: - ptlrpc_stop_all_threads(mds->mds_service); - ptlrpc_unregister_service(mds->mds_service); - return rc; -} - - -static int mdt_cleanup(struct obd_device *obddev) -{ - struct mds_obd *mds = &obddev->u.mds; - ENTRY; - - ptlrpc_stop_all_threads(mds->mds_readpage_service); - ptlrpc_unregister_service(mds->mds_readpage_service); - - ptlrpc_stop_all_threads(mds->mds_setattr_service); - ptlrpc_unregister_service(mds->mds_setattr_service); - - ptlrpc_stop_all_threads(mds->mds_service); - ptlrpc_unregister_service(mds->mds_service); - - 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_owner: THIS_MODULE, - 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_owner: THIS_MODULE, - o_attach: mdt_attach, - o_detach: mdt_detach, - o_setup: mdt_setup, - o_cleanup: mdt_cleanup, -}; - - -static int __init mds_init(void) -{ - struct lprocfs_static_vars lvars; - 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; - - lprocfs_init_multi_vars(0, &lvars); - class_register_type(&mds_obd_ops, lvars.module_vars, LUSTRE_MDS_NAME); - lprocfs_init_multi_vars(1, &lvars); - class_register_type(&mdt_obd_ops, lvars.module_vars, 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, Inc. "); -MODULE_DESCRIPTION("Lustre Metadata Server (MDS)"); -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 e4522fb..0000000 --- a/lustre/mds/lproc_mds.c +++ /dev/null @@ -1,105 +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 -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#endif -#include -#include -#include - -#ifndef LPROCFS -struct lprocfs_vars lprocfs_mds_obd_vars[] = { {0} }; -struct lprocfs_vars lprocfs_mds_module_vars[] = { {0} }; -struct lprocfs_vars lprocfs_mdt_obd_vars[] = { {0} }; -struct lprocfs_vars lprocfs_mdt_module_vars[] = { {0} }; - -#else - -static inline -int lprocfs_mds_statfs(void *data, struct statfs *sfs) -{ - struct obd_device* dev = (struct obd_device*) data; - struct mds_obd *mds; - - LASSERT(dev != NULL); - mds = &dev->u.mds; - return vfs_statfs(mds->mds_sb, sfs); -} - -DEFINE_LPROCFS_STATFS_FCT(rd_blksize, lprocfs_mds_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_kbytestotal, lprocfs_mds_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_kbytesfree, lprocfs_mds_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filestotal, lprocfs_mds_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filesfree, lprocfs_mds_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filegroups, lprocfs_mds_statfs); - -int rd_fstype(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - - LASSERT(obd != NULL); - LASSERT(obd->obd_fsops != NULL); - LASSERT(obd->obd_fsops->fs_type != NULL); - return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type); -} - - -struct lprocfs_vars lprocfs_mds_obd_vars[] = { - { "uuid", lprocfs_rd_uuid, 0, 0 }, - { "blocksize", rd_blksize, 0, 0 }, - { "bytestotal", rd_kbytestotal, 0, 0 }, - { "kbytesfree", rd_kbytesfree, 0, 0 }, - { "fstype", rd_fstype, 0, 0 }, - { "filestotal", rd_filestotal, 0, 0 }, - { "filesfree", rd_filesfree, 0, 0 }, - { "filegroups", rd_filegroups, 0, 0 }, - { 0 } -}; - -struct lprocfs_vars lprocfs_mds_module_vars[] = { - { "num_refs", lprocfs_rd_numrefs, 0, 0 }, - { 0 } -}; - -struct lprocfs_vars lprocfs_mdt_obd_vars[] = { - { "uuid", lprocfs_rd_uuid, 0, 0 }, - { 0 } -}; - -struct lprocfs_vars lprocfs_mdt_module_vars[] = { - { "num_refs", lprocfs_rd_numrefs, 0, 0 }, - { 0 } -}; - -#endif -struct lprocfs_static_vars lprocfs_array_vars[] = { {lprocfs_mds_module_vars, - lprocfs_mds_obd_vars}, - {lprocfs_mdt_module_vars, - lprocfs_mdt_obd_vars}}; - -LPROCFS_INIT_MULTI_VARS(lprocfs_array_vars, - (sizeof(lprocfs_array_vars)/ - sizeof(struct lprocfs_static_vars))) diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c deleted file mode 100644 index 39e8592..0000000 --- a/lustre/mds/mds_fs.c +++ /dev/null @@ -1,396 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * mds/mds_fs.c - * Lustre Metadata Server (MDS) filesystem interface code - * - * Copyright (C) 2002, 2003 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 EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_MDS - -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#endif -#include -#include -#include -#include -#include - -/* 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); - } - CDEBUG(D_INFO, "wrote client mcd at off %u (len %u)\n", - MDS_LR_CLIENT + (cl_off * MDS_LR_SIZE), - (unsigned int)sizeof(*med->med_mcd)); - } - 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); - - off = MDS_LR_CLIENT + (med->med_off * MDS_LR_SIZE); - - CDEBUG(D_INFO, "freeing client at offset %u (%lld)with UUID '%s'\n", - med->med_off, off, med->med_mcd->mcd_uuid); - - if (!test_and_clear_bit(med->med_off, last_rcvd_slots)) { - CERROR("MDS client %u: bit already clear in bitmap!!\n", - med->med_off); - LBUG(); - } - - 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); - } 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; - unsigned long last_rcvd_size = f->f_dentry->d_inode->i_size; - __u64 last_transno = 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); - } - - CDEBUG(D_INODE, "last_rcvd has size %lu (msd + %lu clients)\n", - last_rcvd_size, (last_rcvd_size - MDS_LR_CLIENT)/MDS_LR_SIZE); - - /* - * When we do a clean MDS shutdown, we save the last_transno into - * the header. - */ - last_transno = le64_to_cpu(msd->msd_last_transno); - mds->mds_last_transno = last_transno; - CDEBUG(D_INODE, "got "LPU64" for server last_rcvd value\n", - last_transno); - - last_mount = le64_to_cpu(msd->msd_mount_count); - mds->mds_mount_count = last_mount; - CDEBUG(D_INODE, "got "LPU64" for server last_mount value\n",last_mount); - - /* off is adjusted by lustre_fread, so we don't adjust it in the loop */ - for (off = MDS_LR_CLIENT, cl_off = 0; off < last_rcvd_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) /* XXX fatal error or just abort reading? */ - rc = -EIO; - break; - } - - if (mcd->mcd_uuid[0] == '\0') { - CDEBUG(D_INFO, "skipping zeroed client at offset %d\n", - cl_off); - continue; - } - - last_transno = le64_to_cpu(mcd->mcd_last_transno); - - /* These exports are cleaned up by mds_disconnect(), so they - * need to be set up like real exports as mds_connect() does. - */ - mount_age = last_mount - le64_to_cpu(mcd->mcd_mount_count); - if (mount_age < MDS_MOUNT_RECOV) { - struct obd_export *exp = class_new_export(obddev); - struct mds_export_data *med; - - if (!exp) { - rc = -ENOMEM; - break; - } - - memcpy(&exp->exp_client_uuid.uuid, mcd->mcd_uuid, - sizeof exp->exp_client_uuid.uuid); - med = &exp->exp_mds_data; - med->med_mcd = mcd; - mds_client_add(mds, med, cl_off); - /* create helper if export init gets more complex */ - INIT_LIST_HEAD(&med->med_open_head); - spin_lock_init(&med->med_open_lock); - - mcd = NULL; - obddev->obd_recoverable_clients++; - } 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)); - } - - CDEBUG(D_OTHER, "client at offset %d has last_rcvd = %Lu\n", - cl_off, (unsigned long long)last_transno); - - if (last_transno > mds->mds_last_transno) - mds->mds_last_transno = last_transno; - } - - obddev->obd_last_committed = mds->mds_last_transno; - if (obddev->obd_recoverable_clients) { - CERROR("RECOVERY: %d recoverable clients, last_transno " - LPU64"\n", - obddev->obd_recoverable_clients, mds->mds_last_transno); - obddev->obd_next_recovery_transno = obddev->obd_last_committed - + 1; - obddev->obd_flags |= OBD_RECOVERING; - } - - 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_filp, rc = -ENOENT); - } - - rc = fsfilt_journal_data(obddev, 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; -} - -int mds_fs_setup(struct obd_device *obddev, struct vfsmount *mnt) -{ - struct mds_obd *mds = &obddev->u.mds; - ENTRY; - - 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(); - - RETURN(mds_fs_prep(obddev)); -} - -int mds_fs_cleanup(struct obd_device *obddev) -{ - struct mds_obd *mds = &obddev->u.mds; - struct obd_run_ctxt saved; - int rc = 0; - - class_disconnect_all(obddev); /* this cleans up client info too */ - mds_server_free_data(mds); - - push_ctxt(&saved, &mds->mds_ctxt, NULL); - if (mds->mds_rcvd_filp) { - 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); - - return rc; -} diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c deleted file mode 100644 index 796fcd2..0000000 --- a/lustre/mds/mds_lov.c +++ /dev/null @@ -1,255 +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-2003 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. - */ - -#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, - struct obd_uuid *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; - if (desc->ld_default_stripe_count > desc->ld_tgt_count) { - CERROR("default stripe count %u > OST count %u\n", - desc->ld_default_stripe_count, desc->ld_tgt_count); - RETURN(-EINVAL); - } - if (desc->ld_default_stripe_size & (PAGE_SIZE - 1)) { - CERROR("default stripe size "LPU64" not a multiple of %lu\n", - desc->ld_default_stripe_size, PAGE_SIZE); - RETURN(-EINVAL); - } - if (desc->ld_default_stripe_offset > desc->ld_tgt_count) { - CERROR("default stripe offset "LPU64" > max OST index %u\n", - desc->ld_default_stripe_offset, desc->ld_tgt_count); - RETURN(-EINVAL); - } - if (desc->ld_pattern != 0) { - CERROR("stripe pattern %u unknown\n", - desc->ld_pattern); - RETURN(-EINVAL); - } - - memcpy(&mds->mds_lov_desc, desc, sizeof *desc); - mds->mds_has_lov_desc = 1; - /* XXX the MDS should not really know about this */ - mds->mds_max_mdsize = lov_mds_md_size(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)); - } - -#warning FIXME: if there is an existing LOVDESC, verify new tgt_count > old - 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)); - } - -#warning FIXME: if there is an existing LOVTGTS, verify existing UUIDs same - rc = 0; - for (i = 0; i < tgt_count ; i++) { - rc = lustre_fwrite(f, uuidarray[i].uuid, - sizeof(uuidarray[i]), &f->f_pos); - if (rc != sizeof(uuidarray[i])) { - CERROR("cannot write LOV UUID %s (%d)\n", - uuidarray[i].uuid, 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,struct obd_uuid *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; - struct obd_uuid *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 = (struct obd_uuid *)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 = (struct obd_uuid *)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); - - case OBD_IOC_SET_READONLY: - CERROR("setting device %s read-only\n", - ll_bdevname(obd->u.mds.mds_sb->s_dev)); -#ifdef CONFIG_DEV_RDONLY - dev_set_rdonly(obd->u.mds.mds_sb->s_dev, 2); -#endif - RETURN(0); - - default: - RETURN(-EINVAL); - } - RETURN(0); -} diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c deleted file mode 100644 index 50ca592..0000000 --- a/lustre/mds/mds_open.c +++ /dev/null @@ -1,379 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2003 Cluster File Systems, Inc. - * 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 -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#include -#else -#include -#endif -#include -#include -#include -#include - -extern kmem_cache_t *mds_file_cache; -extern inline struct mds_obd *mds_req2mds(struct ptlrpc_request *req); -int mds_finish_transno(struct mds_obd *mds, struct inode *i, void *handle, - struct ptlrpc_request *req, int rc, __u32 op_data); -extern int enqueue_ordered_locks(int lock_mode, struct obd_device *obd, - struct ldlm_res_id *p1_res_id, - struct ldlm_res_id *p2_res_id, - struct ldlm_res_id *c1_res_id, - struct ldlm_res_id *c2_res_id, - struct lustre_handle *p1_lockh, - struct lustre_handle *p2_lockh, - struct lustre_handle *c1_lockh, - struct lustre_handle *c2_lockh); - -void reconstruct_open(struct mds_update_record *rec, struct ptlrpc_request *req, - struct lustre_handle *child_lockh) -{ - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_client_data *mcd = med->med_mcd; - struct mds_obd *mds = mds_req2mds(req); - struct mds_file_data *mfd; - struct obd_device *obd = req->rq_export->exp_obd; - struct dentry *parent, *child; - struct ldlm_reply *rep = lustre_msg_buf(req->rq_repmsg, 0); - struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 1); - int disp, rc; - ENTRY; - - ENTRY; - - /* copy rc, transno and disp; steal locks */ - req->rq_transno = mcd->mcd_last_transno; - req->rq_status = mcd->mcd_last_result; - disp = rep->lock_policy_res1 = mcd->mcd_last_data; - - if (med->med_outstanding_reply) - mds_steal_ack_locks(med, req); - - /* We never care about these. */ - disp &= ~(IT_OPEN_LOOKUP | IT_OPEN_POS | IT_OPEN_NEG); - if (!disp) { - EXIT; - return; /* error looking up parent or child */ - } - - parent = mds_fid2dentry(mds, rec->ur_fid1, NULL); - LASSERT(!IS_ERR(parent)); - - child = lookup_one_len(lustre_msg_buf(req->rq_reqmsg, 3), - parent, req->rq_reqmsg->buflens[3] - 1); - LASSERT(!IS_ERR(child)); - - if (!child->d_inode) { - GOTO(out_dput, 0); /* child not present to open */ - } - - /* At this point, we know we have a child, which means that we'll send - * it back _unless_ it was open failed, _and_ we didn't create the file. - * I love you guys. No, really. - */ - if (((disp & (IT_OPEN_OPEN | IT_OPEN_CREATE)) == IT_OPEN_OPEN) && - req->rq_status) { - GOTO(out_dput, 0); - } - - if (!med->med_outstanding_reply) { - LBUG(); /* XXX need to get enqueue client lock */ - } - - /* get lock (write for O_CREAT, read otherwise) */ - - mds_pack_inode2fid(&body->fid1, child->d_inode); - mds_pack_inode2body(body, child->d_inode); - if (S_ISREG(child->d_inode->i_mode)) { - rc = mds_pack_md(obd, req->rq_repmsg, 2, body, - child->d_inode); - if (rc) - LASSERT(rc == req->rq_status); - } else { - /* XXX need to check this case */ - } - - /* If we're opening a file without an EA, change to a write - lock (unless we already have one). */ - - /* If we have -EEXIST as the status, and we were asked to create - * exclusively, we can tell we failed because the file already existed. - */ - if (req->rq_status == -EEXIST && - ((rec->ur_flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) { - GOTO(out_dput, 0); - } - - /* If we didn't get as far as trying to open, then some locking thing - * probably went wrong, and we'll just bail here. - */ - if ((disp & IT_OPEN_OPEN) == 0) { - GOTO(out_dput, 0); - } - - /* If we failed, then we must have failed opening, so don't look for - * file descriptor or anything, just give the client the bad news. - */ - if (req->rq_status) { - GOTO(out_dput, 0); - } - - if (med->med_outstanding_reply) { - struct list_head *t; - mfd = NULL; - /* XXX can we just look in the old reply to find the handle in - * XXX O(1) here? */ - list_for_each(t, &med->med_open_head) { - mfd = list_entry(t, struct mds_file_data, mfd_list); - if (mfd->mfd_xid == req->rq_xid) - break; - mfd = NULL; - } - /* if we're not recovering, it had better be found */ - LASSERT(mfd); - } else { - struct file *file; - mfd = kmem_cache_alloc(mds_file_cache, GFP_KERNEL); - if (!mfd) { - CERROR("mds: out of memory\n"); - GOTO(out_dput, req->rq_status = -ENOMEM); - } - mntget(mds->mds_vfsmnt); - file = dentry_open(child, mds->mds_vfsmnt, - rec->ur_flags & ~(O_DIRECT | O_TRUNC)); - LASSERT(!IS_ERR(file)); /* XXX -ENOMEM? */ - file->private_data = mfd; - mfd->mfd_file = file; - mfd->mfd_xid = req->rq_xid; - get_random_bytes(&mfd->mfd_servercookie, - sizeof(mfd->mfd_servercookie)); - spin_lock(&med->med_open_lock); - list_add(&mfd->mfd_list, &med->med_open_head); - spin_unlock(&med->med_open_lock); - } - - body->handle.addr = (__u64)(unsigned long)mfd; - body->handle.cookie = mfd->mfd_servercookie; - - out_dput: - l_dput(child); - l_dput(parent); - EXIT; -} - -int mds_open(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req, struct lustre_handle *child_lockh) -{ - struct mds_obd *mds = mds_req2mds(req); - struct obd_device *obd = req->rq_export->exp_obd; - struct ldlm_reply *rep = lustre_msg_buf(req->rq_repmsg, 0); - struct file *file; - struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 1); - struct dentry *dchild = NULL, *parent; - struct mds_export_data *med; - struct mds_file_data *mfd = NULL; - struct ldlm_res_id child_res_id = { .name = {0} }; - struct lustre_handle parent_lockh; - int rc = 0, parent_mode, child_mode = LCK_PR, lock_flags, created = 0; - int cleanup_phase = 0; - void *handle = NULL; - ENTRY; - - MDS_CHECK_RESENT(req, reconstruct_open(rec, req, child_lockh)); - - med = &req->rq_export->exp_mds_data; - rep->lock_policy_res1 |= IT_OPEN_LOOKUP; - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OPEN_PACK)) { - CERROR("test case OBD_FAIL_MDS_OPEN_PACK\n"); - req->rq_status = -ENOMEM; - RETURN(-ENOMEM); - } - - /* Step 1: Find and lock the parent */ - parent_mode = (rec->ur_flags & O_CREAT) ? LCK_PW : LCK_PR; - parent = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, parent_mode, - &parent_lockh); - if (IS_ERR(parent)) { - rc = PTR_ERR(parent); - CERROR("parent lookup error %d\n", rc); - GOTO(cleanup, rc); - } - LASSERT(parent->d_inode); - - cleanup_phase = 1; /* parent dentry and lock */ - - /* Step 2: Lookup the child */ - dchild = lookup_one_len(lustre_msg_buf(req->rq_reqmsg, 3), - parent, req->rq_reqmsg->buflens[3] - 1); - if (IS_ERR(dchild)) - GOTO(cleanup, rc = PTR_ERR(dchild)); - - cleanup_phase = 2; /* child dentry */ - - if (dchild->d_inode) - rep->lock_policy_res1 |= IT_OPEN_POS; - else - rep->lock_policy_res1 |= IT_OPEN_NEG; - - /* Step 3: If the child was negative, and we're supposed to, - * create it. */ - if (!dchild->d_inode) { - if (!(rec->ur_flags & O_CREAT)) { - /* It's negative and we weren't supposed to create it */ - GOTO(cleanup, rc = -ENOENT); - } - - rep->lock_policy_res1 |= IT_OPEN_CREATE; - handle = fsfilt_start(obd, parent->d_inode, FSFILT_OP_CREATE); - if (IS_ERR(handle)) { - rc = PTR_ERR(handle); - handle = NULL; - GOTO(cleanup, rc); - } - rc = vfs_create(parent->d_inode, dchild, rec->ur_mode); - if (rc) - GOTO(cleanup, rc); - created = 1; - child_mode = LCK_PW; - } - - /* Step 4: It's positive, so lock the child */ - child_res_id.name[0] = dchild->d_inode->i_ino; - child_res_id.name[1] = dchild->d_inode->i_generation; - reacquire: - lock_flags = 0; - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, - child_res_id, LDLM_PLAIN, NULL, 0, child_mode, - &lock_flags, ldlm_completion_ast, - mds_blocking_ast, NULL, NULL, child_lockh); - if (rc != ELDLM_OK) { - CERROR("ldlm_cli_enqueue: %d\n", rc); - GOTO(cleanup, rc = -EIO); - } - - cleanup_phase = 3; /* child lock */ - - mds_pack_inode2fid(&body->fid1, dchild->d_inode); - mds_pack_inode2body(body, dchild->d_inode); - if (S_ISREG(dchild->d_inode->i_mode)) { - rc = mds_pack_md(obd, req->rq_repmsg, 2, body, dchild->d_inode); - if (rc) - GOTO(cleanup, rc); - } else { - /* If this isn't a regular file, we can't open it. */ - - /* We want to drop the child dentry, because we're not returning - * failure (which would do this for us in step 2), and we're not - * handing it off to the open file in dentry_open. */ - l_dput(dchild); - GOTO(cleanup, rc = 0); /* returns the lock to the client */ - } - - if (!created && (rec->ur_flags & O_CREAT) && (rec->ur_flags & O_EXCL)) { - /* File already exists, we didn't just create it, and we - * were passed O_EXCL; err-or. */ - GOTO(cleanup, rc = -EEXIST); // returns a lock to the client - } - - /* If we're opening a file without an EA, the client needs a write - * lock. */ - if (child_mode != LCK_PW && !(body->valid & OBD_MD_FLEASIZE)) { - ldlm_lock_decref(child_lockh, child_mode); - child_mode = LCK_PW; - goto reacquire; - } - - /* Step 5: Open it */ - rep->lock_policy_res1 |= IT_OPEN_OPEN; - mfd = kmem_cache_alloc(mds_file_cache, GFP_KERNEL); - if (!mfd) { - CERROR("mds: out of memory\n"); - GOTO(cleanup, rc = -ENOMEM); - } - - cleanup_phase = 4; /* mfd allocated */ - - /* dentry_open does a dput(de) and mntput(mds->mds_vfsmnt) on error */ - mntget(mds->mds_vfsmnt); - file = dentry_open(dchild, mds->mds_vfsmnt, - rec->ur_flags & ~(O_DIRECT | O_TRUNC)); - if (IS_ERR(file)) { - dchild = NULL; /* prevent a double dput in step 2 */ - GOTO(cleanup, rc = PTR_ERR(file)); - } - - file->private_data = mfd; - mfd->mfd_file = file; - mfd->mfd_xid = req->rq_xid; - get_random_bytes(&mfd->mfd_servercookie, sizeof(mfd->mfd_servercookie)); - spin_lock(&med->med_open_lock); - list_add(&mfd->mfd_list, &med->med_open_head); - spin_unlock(&med->med_open_lock); - - body->handle.addr = (__u64)(unsigned long)mfd; - body->handle.cookie = mfd->mfd_servercookie; - CDEBUG(D_INODE, "file %p: mfd %p, cookie "LPX64"\n", - mfd->mfd_file, mfd, mfd->mfd_servercookie); - GOTO(cleanup, rc = 0); /* returns a lock to the client */ - - cleanup: - rc = mds_finish_transno(mds, dchild ? dchild->d_inode : NULL, handle, - req, rc, rep->lock_policy_res1); - switch (cleanup_phase) { - case 4: - if (rc) - kmem_cache_free(mds_file_cache, mfd); - case 3: - /* This is the same logic as in the IT_OPEN part of - * ldlm_intent_policy: if we found the dentry, or we tried to - * open it (meaning that we created, if it wasn't found), then - * we return the lock to the caller and client. */ - if (!(rep->lock_policy_res1 & (IT_OPEN_OPEN | IT_OPEN_POS))) - ldlm_lock_decref(child_lockh, child_mode); - case 2: - if (rc) - l_dput(dchild); - case 1: - l_dput(parent); - if (rc) { - ldlm_lock_decref(&parent_lockh, parent_mode); - } else { - memcpy(&req->rq_ack_locks[0].lock, &parent_lockh, - sizeof(parent_lockh)); - req->rq_ack_locks[0].mode = parent_mode; - } - } - RETURN(rc); -} diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c deleted file mode 100644 index 583ba4a..0000000 --- a/lustre/mds/mds_reint.c +++ /dev/null @@ -1,1175 +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, 2003 Cluster File Systems, Inc. - * Author: Peter Braam - * Author: Andreas Dilger - * 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_MDS - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern inline struct mds_obd *mds_req2mds(struct ptlrpc_request *req); - -static void mds_last_rcvd_cb(struct obd_device *obd, __u64 last_rcvd, int error) -{ - CDEBUG(D_HA, "got callback for last_rcvd "LPD64": rc = %d\n", - last_rcvd, error); - if (!error && last_rcvd > obd->obd_last_committed) - obd->obd_last_committed = last_rcvd; -} - -/* Assumes caller has already pushed us into the kernel context. */ -int mds_finish_transno(struct mds_obd *mds, struct inode *i, void *handle, - struct ptlrpc_request *req, int rc, - __u32 op_data) -{ - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_client_data *mcd = med->med_mcd; - struct obd_device *obd = req->rq_export->exp_obd; - int started_handle = 0, err; - __u64 transno; - loff_t off; - ssize_t written; - ENTRY; - - /* we don't allocate new transnos for replayed requests */ - if (req->rq_level == LUSTRE_CONN_RECOVD) - GOTO(out, rc = rc); - - if (!handle) { - /* if we're starting our own xaction, use our own inode */ - i = mds->mds_rcvd_filp->f_dentry->d_inode; - handle = fsfilt_start(obd, i, FSFILT_OP_SETATTR); - if (IS_ERR(handle)) { - CERROR("fsfilt_start: %ld\n", PTR_ERR(handle)); - GOTO(out, rc = PTR_ERR(handle)); - } - started_handle = 1; - } - - off = MDS_LR_CLIENT + med->med_off * MDS_LR_SIZE; - - spin_lock(&mds->mds_transno_lock); - transno = ++mds->mds_last_transno; - spin_unlock(&mds->mds_transno_lock); - req->rq_repmsg->transno = req->rq_transno = HTON__u64(transno); - mcd->mcd_last_transno = cpu_to_le64(transno); - mcd->mcd_mount_count = cpu_to_le64(mds->mds_mount_count); - mcd->mcd_last_xid = cpu_to_le64(req->rq_xid); - mcd->mcd_last_result = cpu_to_le32(rc); - mcd->mcd_last_data = cpu_to_le32(op_data); - - fsfilt_set_last_rcvd(req->rq_export->exp_obd, transno, handle, - mds_last_rcvd_cb); - written = lustre_fwrite(mds->mds_rcvd_filp, (char *)mcd, sizeof(*mcd), - &off); - CDEBUG(D_INODE, "wrote trans "LPU64" client %s at #%u: written = " - LPSZ"\n", transno, mcd->mcd_uuid, med->med_off, written); - - if (written != sizeof(*mcd)) { - CERROR("error writing to last_rcvd: rc = "LPSZ"\n", written); - if (rc == 0) { - if (written < 0) - rc = written; - else - rc = -EIO; - } - } - - err = fsfilt_commit(obd, i, handle); - if (err) { - CERROR("error committing transaction: %d\n", err); - if (!rc) - rc = err; - } - - EXIT; - out: - return rc; -} - -/* this gives the same functionality as the code between - * sys_chmod and inode_setattr - * chown_common and inode_setattr - * utimes and inode_setattr - */ -int mds_fix_attr(struct inode *inode, struct mds_update_record *rec) -{ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - time_t now = CURRENT_TIME; -#else - time_t now = CURRENT_TIME.tv_sec; -#endif - struct iattr *attr = &rec->ur_iattr; - unsigned int ia_valid = attr->ia_valid; - int error; - ENTRY; - - /* only fix up attrs if the client VFS didn't already */ - if (!(ia_valid & ATTR_RAW)) - RETURN(0); - - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - RETURN(-EPERM); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - attr->ia_ctime = now; - if (!(ia_valid & ATTR_ATIME_SET)) - attr->ia_atime = now; - if (!(ia_valid & ATTR_MTIME_SET)) - attr->ia_mtime = now; -#else - attr->ia_ctime.tv_sec = now; - if (!(ia_valid & ATTR_ATIME_SET)) - attr->ia_atime.tv_sec = now; - if (!(ia_valid & ATTR_MTIME_SET)) - attr->ia_mtime.tv_sec = now; -#endif - - /* times */ - if ((ia_valid & (ATTR_MTIME|ATTR_ATIME))==(ATTR_MTIME|ATTR_ATIME) && - !(ia_valid & ATTR_ATIME_SET)) { - if (rec->ur_fsuid != inode->i_uid && - (error = permission(inode,MAY_WRITE)) != 0) - RETURN(error); - } else if (ia_valid & ATTR_UID) { - /* chown */ - error = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - RETURN(-EPERM); - if (attr->ia_uid == (uid_t) -1) - attr->ia_uid = inode->i_uid; - if (attr->ia_gid == (gid_t) -1) - attr->ia_gid = inode->i_gid; - attr->ia_mode = inode->i_mode; - attr->ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME; - /* - * If the user or group of a non-directory has been - * changed by a non-root user, remove the setuid bit. - * 19981026 David C Niemi - * - * Changed this to apply to all users, including root, - * to avoid some races. This is the behavior we had in - * 2.0. The check for non-root was definitely wrong - * for 2.2 anyway, as it should have been using - * CAP_FSETID rather than fsuid -- 19990830 SD. - */ - if ((inode->i_mode & S_ISUID) == S_ISUID && - !S_ISDIR(inode->i_mode)) { - attr->ia_mode &= ~S_ISUID; - attr->ia_valid |= ATTR_MODE; - } - /* - * Likewise, if the user or group of a non-directory - * has been changed by a non-root user, remove the - * setgid bit UNLESS there is no group execute bit - * (this would be a file marked for mandatory - * locking). 19981026 David C Niemi - * - * Removed the fsuid check (see the comment above) -- - * 19990830 SD. - */ - if (((inode->i_mode & (S_ISGID | S_IXGRP)) == - (S_ISGID | S_IXGRP)) && !S_ISDIR(inode->i_mode)) { - attr->ia_mode &= ~S_ISGID; - attr->ia_valid |= ATTR_MODE; - } - } else if (ia_valid & ATTR_MODE) { - int mode = attr->ia_mode; - /* chmod */ - if (attr->ia_mode == (mode_t) -1) - attr->ia_mode = inode->i_mode; - attr->ia_mode = - (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - } - RETURN(0); -} - -static void reconstruct_reint_setattr(struct mds_update_record *rec, - int offset, struct ptlrpc_request *req) -{ - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_client_data *mcd = med->med_mcd; - struct mds_obd *obd = &req->rq_export->exp_obd->u.mds; - struct dentry *de; - struct mds_body *body; - - req->rq_transno = mcd->mcd_last_transno; - req->rq_status = mcd->mcd_last_result; - - if (med->med_outstanding_reply) - mds_steal_ack_locks(med, req); - - de = mds_fid2dentry(obd, rec->ur_fid1, NULL); - if (IS_ERR(de)) { - LASSERT(PTR_ERR(de) == req->rq_status); - return; - } - - body = lustre_msg_buf(req->rq_repmsg, 0); - mds_pack_inode2fid(&body->fid1, de->d_inode); - mds_pack_inode2body(body, de->d_inode); - - l_dput(de); -} - -/* In the raw-setattr case, we lock the child inode. - * In the write-back case or if being called from open, the client holds a lock - * already. - * - * We use the ATTR_FROM_OPEN flag to tell these cases apart. */ -static int mds_reint_setattr(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req, - struct lustre_handle *lh) -{ - 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 = NULL; - struct lustre_handle lockh; - void *handle = NULL; - int rc = 0, cleanup_phase = 0, err, locked = 0; - ENTRY; - - MDS_CHECK_RESENT(req, reconstruct_reint_setattr(rec, offset, req)); - - if (rec->ur_iattr.ia_valid & ATTR_FROM_OPEN) { - de = mds_fid2dentry(mds, rec->ur_fid1, NULL); - if (IS_ERR(de)) - GOTO(cleanup, rc = PTR_ERR(de)); - } else { - de = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, LCK_PW, - &lockh); - if (IS_ERR(de)) - GOTO(cleanup, rc = PTR_ERR(de)); - locked = 1; - } - - cleanup_phase = 1; - inode = de->d_inode; - LASSERT(inode); - - CDEBUG(D_INODE, "ino %lu\n", inode->i_ino); - - OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_SETATTR_WRITE, - to_kdev_t(inode->i_sb->s_dev)); - - handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR); - if (IS_ERR(handle)) { - rc = PTR_ERR(handle); - handle = NULL; - GOTO(cleanup, rc); - } - - rc = mds_fix_attr(inode, rec); - if (rc) - GOTO(cleanup, rc); - - rc = fsfilt_setattr(obd, de, handle, &rec->ur_iattr); - if (rc == 0 && S_ISREG(inode->i_mode) && - req->rq_reqmsg->bufcount > 1) { - rc = fsfilt_set_md(obd, inode, handle, - lustre_msg_buf(req->rq_reqmsg, 1), - req->rq_reqmsg->buflens[1]); - } - - body = lustre_msg_buf(req->rq_repmsg, 0); - mds_pack_inode2fid(&body->fid1, inode); - mds_pack_inode2body(body, inode); - - EXIT; - cleanup: - err = mds_finish_transno(mds, inode, handle, req, rc, 0); - switch(cleanup_phase) { - case 1: - l_dput(de); - if (locked) { - if (rc) { - ldlm_lock_decref(&lockh, LCK_PW); - } else { - memcpy(&req->rq_ack_locks[0].lock, &lockh, - sizeof(lockh)); - req->rq_ack_locks[0].mode = LCK_PW; - } - } - case 0: - break; - default: - LBUG(); - } - if (err && !rc) - rc = err; - - req->rq_status = rc; - return 0; -} - -static void reconstruct_reint_create(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req) -{ - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_client_data *mcd = med->med_mcd; - struct mds_obd *obd = &req->rq_export->exp_obd->u.mds; - struct dentry *parent, *child; - struct mds_body *body; - - req->rq_transno = mcd->mcd_last_transno; - req->rq_status = mcd->mcd_last_result; - - if (med->med_outstanding_reply) - mds_steal_ack_locks(med, req); - - if (req->rq_status) - return; - - parent = mds_fid2dentry(obd, rec->ur_fid1, NULL); - LASSERT(!IS_ERR(parent)); - child = lookup_one_len(rec->ur_name, parent, rec->ur_namelen - 1); - LASSERT(!IS_ERR(child)); - body = lustre_msg_buf(req->rq_repmsg, offset); - mds_pack_inode2fid(&body->fid1, child->d_inode); - mds_pack_inode2body(body, child->d_inode); - l_dput(parent); - l_dput(child); -} - -static int mds_reint_create(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req, - struct lustre_handle *lh) -{ - 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 = NULL; - void *handle = NULL; - struct lustre_handle lockh; - int rc = 0, err, type = rec->ur_mode & S_IFMT, cleanup_phase = 0; - int created = 0; - ENTRY; - - LASSERT(offset == 0); - LASSERT(!strcmp(req->rq_export->exp_obd->obd_type->typ_name, "mds")); - - MDS_CHECK_RESENT(req, reconstruct_reint_create(rec, offset, req)); - - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_CREATE)) - GOTO(cleanup, rc = -ESTALE); - - de = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, LCK_PW, &lockh); - if (IS_ERR(de)) { - rc = PTR_ERR(de); - CERROR("parent lookup error %d\n", rc); - GOTO(cleanup, rc); - } - cleanup_phase = 1; /* locked parent dentry */ - dir = de->d_inode; - LASSERT(dir); - CDEBUG(D_INODE, "parent ino %lu creating name %s mode %o\n", - dir->i_ino, rec->ur_name, rec->ur_mode); - - ldlm_lock_dump_handle(D_OTHER, &lockh); - - dchild = lookup_one_len(rec->ur_name, de, rec->ur_namelen - 1); - if (IS_ERR(dchild)) { - rc = PTR_ERR(dchild); - CERROR("child lookup error %d\n", rc); - GOTO(cleanup, rc); - } - - cleanup_phase = 2; /* child dentry */ - - 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; - } - - if (rec->ur_fid2->id) - dchild->d_fsdata = (void *)(unsigned long)rec->ur_fid2->id; - else - LASSERT(!(rec->ur_opcode & REINT_REPLAYING)); - - switch (type) { - case S_IFREG:{ - handle = fsfilt_start(obd, dir, FSFILT_OP_CREATE); - if (IS_ERR(handle)) - GOTO(cleanup, rc = PTR_ERR(handle)); - rc = vfs_create(dir, dchild, rec->ur_mode); - EXIT; - break; - } - case S_IFDIR:{ - handle = fsfilt_start(obd, dir, FSFILT_OP_MKDIR); - if (IS_ERR(handle)) - GOTO(cleanup, rc = PTR_ERR(handle)); - rc = vfs_mkdir(dir, dchild, rec->ur_mode); - EXIT; - break; - } - case S_IFLNK:{ - handle = fsfilt_start(obd, dir, FSFILT_OP_SYMLINK); - if (IS_ERR(handle)) - GOTO(cleanup, rc = PTR_ERR(handle)); - rc = vfs_symlink(dir, dchild, rec->ur_tgt); - EXIT; - break; - } - case S_IFCHR: - case S_IFBLK: - case S_IFIFO: - case S_IFSOCK:{ - int rdev = rec->ur_rdev; - handle = fsfilt_start(obd, dir, FSFILT_OP_MKNOD); - if (IS_ERR(handle)) - GOTO(cleanup, (handle = NULL, 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); - GOTO(cleanup, rc = -EINVAL); - } - - /* In case we stored the desired inum in here, we want to clean up. - * We also do this in the cleanup block, for the error cases. - */ - dchild->d_fsdata = NULL; - - if (rc) { - CDEBUG(D_INODE, "error during create: %d\n", rc); - GOTO(cleanup, rc); - } else { - struct iattr iattr; - struct inode *inode = dchild->d_inode; - struct mds_body *body; - - created = 1; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - iattr.ia_atime = rec->ur_time; - iattr.ia_ctime = rec->ur_time; - iattr.ia_mtime = rec->ur_time; -#else - iattr.ia_atime.tv_sec = rec->ur_time; - iattr.ia_ctime.tv_sec = rec->ur_time; - iattr.ia_mtime.tv_sec = rec->ur_time; -#endif - 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_fid2->id == inode->i_ino); - inode->i_generation = rec->ur_fid2->generation; - /* Dirtied and committed by the upcoming setattr. */ - CDEBUG(D_INODE, "recreated ino %lu with gen %x\n", - inode->i_ino, inode->i_generation); - } else { - CDEBUG(D_INODE, "created ino %lu with gen %x\n", - inode->i_ino, inode->i_generation); - } - - rc = fsfilt_setattr(obd, 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; - -cleanup: - err = mds_finish_transno(mds, dir, handle, req, rc, 0); - - if (rc && created) { - /* 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("rmdir in error path: %d\n", err); - break; - default: - err = vfs_unlink(dir, dchild); - if (err) - CERROR("unlink in error path: %d\n", err); - break; - } - } else { - rc = err; - } - switch (cleanup_phase) { - case 2: /* child dentry */ - dchild->d_fsdata = NULL; - l_dput(dchild); - case 1: /* locked parent dentry */ - if (rc) { - ldlm_lock_decref(&lockh, LCK_PW); - } else { - memcpy(&req->rq_ack_locks[0].lock, &lockh, - sizeof(lockh)); - req->rq_ack_locks[0].mode = LCK_PW; - } - l_dput(de); - case 0: - break; - default: - CERROR("invalid cleanup_phase %d\n", cleanup_phase); - LBUG(); - } - req->rq_status = rc; - return 0; -} - -/* This function doesn't use ldlm_match_or_enqueue because we're always called - * with EX or PW locks, and the MDS is no longer allowed to match write locks, - * because they take the place of local semaphores. - * - * Two locks are taken in numerical order */ -int enqueue_ordered_locks(int lock_mode, struct obd_device *obd, - struct ldlm_res_id *p1_res_id, - struct ldlm_res_id *p2_res_id, - struct lustre_handle *p1_lockh, - struct lustre_handle *p2_lockh) -{ - struct ldlm_res_id res_id[2]; - struct lustre_handle *handles[2] = {p1_lockh, p2_lockh}; - int rc, flags; - ENTRY; - - LASSERT(p1_res_id != NULL && p2_res_id != NULL); - - CDEBUG(D_INFO, "locks before: "LPU64"/"LPU64"\n", - p1_res_id[0].name[0], p2_res_id[0].name[0]); - - if (p1_res_id->name[0] < p2_res_id->name[0]) { - handles[0] = p1_lockh; - handles[1] = p2_lockh; - res_id[0] = *p1_res_id; - res_id[1] = *p2_res_id; - } else { - handles[1] = p1_lockh; - handles[0] = p2_lockh; - res_id[1] = *p1_res_id; - res_id[0] = *p2_res_id; - } - - CDEBUG(D_INFO, "lock order: "LPU64"/"LPU64"\n", - p1_res_id[0].name[0], p2_res_id[0].name[0]); - - flags = LDLM_FL_LOCAL_ONLY; - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, res_id[0], - LDLM_PLAIN, NULL, 0, lock_mode, &flags, - ldlm_completion_ast, mds_blocking_ast, NULL, - NULL, handles[0]); - if (rc != ELDLM_OK) - RETURN(-EIO); - ldlm_lock_dump_handle(D_OTHER, handles[0]); - - if (memcmp(&res_id[0], &res_id[1], sizeof(res_id[0])) == 0) { - memcpy(handles[1], handles[0], sizeof(*(handles[1]))); - ldlm_lock_addref(handles[1], lock_mode); - } else { - flags = LDLM_FL_LOCAL_ONLY; - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, - res_id[1], LDLM_PLAIN, NULL, 0, lock_mode, - &flags, ldlm_completion_ast, - mds_blocking_ast, NULL, 0, handles[1]); - if (rc != ELDLM_OK) { - ldlm_lock_decref(handles[0], lock_mode); - RETURN(-EIO); - } - } - ldlm_lock_dump_handle(D_OTHER, handles[1]); - - RETURN(0); -} - -static void reconstruct_reint_unlink(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req, - struct lustre_handle *child_lockh) -{ - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_client_data *mcd = med->med_mcd; - - req->rq_transno = mcd->mcd_last_transno; - req->rq_status = mcd->mcd_last_result; - - if (med->med_outstanding_reply) - mds_steal_ack_locks(med, req); - - DEBUG_REQ(D_ERROR, req, - "can't get EA for reconstructed unlink, leaking OST inodes"); -} - -static int mds_reint_unlink(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req, - struct lustre_handle *child_lockh) -{ - struct dentry *dir_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; - struct inode *dir_inode = NULL, *child_inode; - struct lustre_handle parent_lockh; - void *handle = NULL; - struct ldlm_res_id child_res_id = { .name = {0} }; - char *name; - int namelen, rc = 0, flags = 0, return_lock = 0; - int cleanup_phase = 0; - ENTRY; - - MDS_CHECK_RESENT(req, reconstruct_reint_unlink(rec, offset, req, - child_lockh)); - - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_UNLINK)) - GOTO(cleanup, rc = -ENOENT); - - /* Step 1: Lookup the parent by FID */ - dir_de = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, LCK_PW, - &parent_lockh); - if (IS_ERR(dir_de)) - GOTO(cleanup, rc = PTR_ERR(dir_de)); - dir_inode = dir_de->d_inode; - LASSERT(dir_inode); - - cleanup_phase = 1; /* Have parent dentry lock */ - - /* Step 2: Lookup the child */ - name = lustre_msg_buf(req->rq_reqmsg, offset + 1); - namelen = req->rq_reqmsg->buflens[offset + 1] - 1; - - dchild = lookup_one_len(name, dir_de, namelen); - if (IS_ERR(dchild)) - GOTO(cleanup, rc = PTR_ERR(dchild)); - - cleanup_phase = 2; /* child dentry */ - - child_inode = dchild->d_inode; - if (child_inode == NULL) { - if (rec->ur_opcode & REINT_REPLAYING) { - CDEBUG(D_INODE, - "child missing (%lu/%s); OK for REPLAYING\n", - dir_inode->i_ino, rec->ur_name); - rc = 0; - } else { - CDEBUG(D_INODE, - "child doesn't exist (dir %lu, name %s)\n", - dir_inode->i_ino, rec->ur_name); - rc = -ENOENT; - } - GOTO(cleanup, rc); - } - - DEBUG_REQ(D_INODE, req, "parent ino %lu, child ino %lu", - dir_inode->i_ino, child_inode->i_ino); - - /* Step 3: Get a lock on the child */ - child_res_id.name[0] = child_inode->i_ino; - child_res_id.name[1] = child_inode->i_generation; - - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, - child_res_id, LDLM_PLAIN, NULL, 0, LCK_EX, - &flags, ldlm_completion_ast, mds_blocking_ast, - NULL, NULL, child_lockh); - if (rc != ELDLM_OK) - GOTO(cleanup, rc); - - cleanup_phase = 3; /* child lock */ - - OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_UNLINK_WRITE, - to_kdev_t(dir_inode->i_sb->s_dev)); - - /* Slightly magical; see ldlm_intent_policy */ - if (offset) - offset = 1; - - body = lustre_msg_buf(req->rq_repmsg, offset); - - /* Step 4: Do the unlink: client decides between rmdir/unlink! - * (bug 72) */ - switch (rec->ur_mode & S_IFMT) { - case S_IFDIR: - handle = fsfilt_start(obd, dir_inode, FSFILT_OP_RMDIR); - if (IS_ERR(handle)) - GOTO(cleanup, rc = PTR_ERR(handle)); - rc = vfs_rmdir(dir_inode, dchild); - break; - case S_IFREG: - /* If this is the last reference to this inode, get the OBD EA - * data first so the client can destroy OST objects */ - if ((child_inode->i_mode & S_IFMT) == S_IFREG && - child_inode->i_nlink == 1) { - mds_pack_inode2fid(&body->fid1, child_inode); - mds_pack_inode2body(body, child_inode); - mds_pack_md(obd, req->rq_repmsg, offset + 1, - body, child_inode); - if (body->valid & OBD_MD_FLEASIZE) - return_lock = 1; - } - /* no break */ - case S_IFLNK: - case S_IFCHR: - case S_IFBLK: - case S_IFIFO: - case S_IFSOCK: - handle = fsfilt_start(obd, dir_inode, FSFILT_OP_UNLINK); - if (IS_ERR(handle)) - GOTO(cleanup, rc = PTR_ERR(handle)); - rc = vfs_unlink(dir_inode, dchild); - break; - default: - CERROR("bad file type %o unlinking %s\n", rec->ur_mode, name); - LBUG(); - GOTO(cleanup, rc = -EINVAL); - } - - cleanup: - rc = mds_finish_transno(mds, dir_inode, handle, req, rc, 0); - if (rc && body) { - /* Don't unlink the OST objects if the MDS unlink failed */ - body->valid = 0; - } - switch(cleanup_phase) { - case 3: /* child lock */ - if (rc != 0 || return_lock == 0) - ldlm_lock_decref(child_lockh, LCK_EX); - case 2: /* child dentry */ - l_dput(dchild); - case 1: /* parent dentry and lock */ - if (rc) { - ldlm_lock_decref(&parent_lockh, LCK_EX); - } else { - memcpy(&req->rq_ack_locks[0].lock, &parent_lockh, - sizeof(parent_lockh)); - req->rq_ack_locks[0].mode = LCK_EX; - } - l_dput(dir_de); - case 0: - break; - default: - CERROR("invalid cleanup_phase %d\n", cleanup_phase); - LBUG(); - } - req->rq_status = rc; - return 0; -} - -static void reconstruct_reint_link(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req) -{ - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_client_data *mcd = med->med_mcd; - - req->rq_transno = mcd->mcd_last_transno; - req->rq_status = mcd->mcd_last_result; - - if (med->med_outstanding_reply) - mds_steal_ack_locks(med, req); - else - LBUG(); /* don't support it yet, but it'll be fun! */ -} - -static int mds_reint_link(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req, - struct lustre_handle *lh) -{ - 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 = NULL, tgt_dir_lockh, src_lockh; - struct ldlm_res_id src_res_id = { .name = {0} }; - struct ldlm_res_id tgt_dir_res_id = { .name = {0} }; - int lock_mode = 0, rc = 0, cleanup_phase = 0; - ENTRY; - - MDS_CHECK_RESENT(req, reconstruct_reint_link(rec, offset, req)); - - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_LINK)) - GOTO(cleanup, rc = -ENOENT); - - /* Step 1: Lookup the source inode and target directory by FID */ - de_src = mds_fid2dentry(mds, rec->ur_fid1, NULL); - if (IS_ERR(de_src)) - GOTO(cleanup, rc = PTR_ERR(de_src)); - - cleanup_phase = 1; /* source dentry */ - - de_tgt_dir = mds_fid2dentry(mds, rec->ur_fid2, NULL); - if (IS_ERR(de_tgt_dir)) - GOTO(cleanup, rc = PTR_ERR(de_tgt_dir)); - - cleanup_phase = 2; /* target directory dentry */ - - CDEBUG(D_INODE, "linking %*s/%s to inode %lu\n", - de_tgt_dir->d_name.len, de_tgt_dir->d_name.name, rec->ur_name, - de_src->d_inode->i_ino); - - /* Step 2: Take the two locks */ - lock_mode = LCK_EX; - src_res_id.name[0] = de_src->d_inode->i_ino; - src_res_id.name[1] = de_src->d_inode->i_generation; - tgt_dir_res_id.name[0] = de_tgt_dir->d_inode->i_ino; - tgt_dir_res_id.name[1] = de_tgt_dir->d_inode->i_generation; - - rc = enqueue_ordered_locks(LCK_EX, obd, &src_res_id, &tgt_dir_res_id, - &src_lockh, &tgt_dir_lockh); - if (rc != ELDLM_OK) - GOTO(cleanup, rc = -EIO); - - cleanup_phase = 3; /* locks */ - - /* Step 3: Lookup the child */ - 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(cleanup, rc = PTR_ERR(dchild)); - } - - cleanup_phase = 4; /* child dentry */ - - if (dchild->d_inode) { - if (rec->ur_opcode & REINT_REPLAYING) { - /* XXX verify that the link is to the the right file? */ - CDEBUG(D_INODE, - "child exists (dir %lu, name %s) (REPLAYING)\n", - de_tgt_dir->d_inode->i_ino, rec->ur_name); - rc = 0; - } else { - CDEBUG(D_INODE, "child exists (dir %lu, name %s)\n", - de_tgt_dir->d_inode->i_ino, rec->ur_name); - rc = -EEXIST; - } - GOTO(cleanup, rc); - } - - /* Step 4: Do it. */ - OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_LINK_WRITE, - to_kdev_t(de_src->d_inode->i_sb->s_dev)); - - handle = fsfilt_start(obd, de_tgt_dir->d_inode, FSFILT_OP_LINK); - if (IS_ERR(handle)) { - rc = PTR_ERR(handle); - GOTO(cleanup, rc); - } - - rc = vfs_link(de_src, de_tgt_dir->d_inode, dchild); - if (rc) - CERROR("link error %d\n", rc); -cleanup: - rc = mds_finish_transno(mds, de_tgt_dir ? de_tgt_dir->d_inode : NULL, - handle, req, rc, 0); - EXIT; - - switch (cleanup_phase) { - case 4: /* child dentry */ - l_dput(dchild); - case 3: /* locks */ - if (rc) { - ldlm_lock_decref(&src_lockh, lock_mode); - ldlm_lock_decref(&tgt_dir_lockh, lock_mode); - } else { - memcpy(&req->rq_ack_locks[0].lock, &src_lockh, - sizeof(src_lockh)); - memcpy(&req->rq_ack_locks[1].lock, &tgt_dir_lockh, - sizeof(tgt_dir_lockh)); - req->rq_ack_locks[0].mode = lock_mode; - req->rq_ack_locks[1].mode = lock_mode; - } - case 2: /* target dentry */ - l_dput(de_tgt_dir); - case 1: /* source dentry */ - l_dput(de_src); - case 0: - break; - default: - CERROR("invalid cleanup_phase %d\n", cleanup_phase); - LBUG(); - } - req->rq_status = rc; - return 0; -} - -static void reconstruct_reint_rename(struct mds_update_record *rec, - int offset, struct ptlrpc_request *req) -{ - struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_client_data *mcd = med->med_mcd; - - req->rq_transno = mcd->mcd_last_transno; - req->rq_status = mcd->mcd_last_result; - - if (med->med_outstanding_reply) - mds_steal_ack_locks(med, req); - else - LBUG(); /* don't support it yet, but it'll be fun! */ - -} - -static int mds_reint_rename(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req, - struct lustre_handle *lockh) -{ - 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 dlm_handles[4]; - struct ldlm_res_id p1_res_id = { .name = {0} }; - struct ldlm_res_id p2_res_id = { .name = {0} }; - struct ldlm_res_id c1_res_id = { .name = {0} }; - struct ldlm_res_id c2_res_id = { .name = {0} }; - int rc = 0, lock_count = 3, flags = LDLM_FL_LOCAL_ONLY; - int cleanup_phase = 0; - void *handle = NULL; - ENTRY; - - MDS_CHECK_RESENT(req, reconstruct_reint_rename(rec, offset, req)); - - de_srcdir = mds_fid2dentry(mds, rec->ur_fid1, NULL); - if (IS_ERR(de_srcdir)) - GOTO(cleanup, rc = PTR_ERR(de_srcdir)); - - cleanup_phase = 1; /* source directory dentry */ - - de_tgtdir = mds_fid2dentry(mds, rec->ur_fid2, NULL); - if (IS_ERR(de_tgtdir)) - GOTO(cleanup, rc = PTR_ERR(de_tgtdir)); - - cleanup_phase = 2; /* target directory dentry */ - - /* The idea here is that we need to get four locks in the end: - * one on each parent directory, one on each child. We need to take - * these locks in some kind of order (to avoid deadlocks), and the order - * I selected is "increasing resource number" order. We need to take - * the locks on the parent directories, however, before we can lookup - * the children. Thus the following plan: - * - * 1. Take locks on the parent(s), in order - * 2. Lookup the children - * 3. Take locks on the children, in order - * 4. Execute the rename - */ - - /* Step 1: Take locks on the parent(s), in order */ - p1_res_id.name[0] = de_srcdir->d_inode->i_ino; - p1_res_id.name[1] = de_srcdir->d_inode->i_generation; - - p2_res_id.name[0] = de_tgtdir->d_inode->i_ino; - p2_res_id.name[1] = de_tgtdir->d_inode->i_generation; - - rc = enqueue_ordered_locks(LCK_EX, obd, &p1_res_id, &p2_res_id, - &(dlm_handles[0]), &(dlm_handles[1])); - if (rc != ELDLM_OK) - GOTO(cleanup, rc); - - cleanup_phase = 3; /* parent locks */ - - /* Step 2: Lookup the children */ - 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(cleanup, rc = PTR_ERR(de_old)); - } - - cleanup_phase = 4; /* original name dentry */ - - if (de_old->d_inode == NULL) - GOTO(cleanup, rc = -ENOENT); - - /* sanity check for src inode */ - if (de_old->d_inode->i_ino == de_srcdir->d_inode->i_ino || - de_old->d_inode->i_ino == de_tgtdir->d_inode->i_ino) - GOTO(cleanup, rc = -EINVAL); - - 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(cleanup, rc = PTR_ERR(de_new)); - } - - cleanup_phase = 5; /* target dentry */ - - /* sanity check for dest inode */ - if (de_new->d_inode && - (de_new->d_inode->i_ino == de_srcdir->d_inode->i_ino || - de_new->d_inode->i_ino == de_tgtdir->d_inode->i_ino)) - GOTO(cleanup, rc = -EINVAL); - - /* Step 3: Take locks on the children */ - c1_res_id.name[0] = de_old->d_inode->i_ino; - c1_res_id.name[1] = de_old->d_inode->i_generation; - if (de_new->d_inode == NULL) { - flags = LDLM_FL_LOCAL_ONLY; - rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, - c1_res_id, LDLM_PLAIN, NULL, 0, LCK_EX, - &flags, ldlm_completion_ast, - mds_blocking_ast, NULL, NULL, - &(dlm_handles[2])); - lock_count = 3; - } else { - c2_res_id.name[0] = de_new->d_inode->i_ino; - c2_res_id.name[1] = de_new->d_inode->i_generation; - rc = enqueue_ordered_locks(LCK_EX, obd, &c1_res_id, &c2_res_id, - &(dlm_handles[2]), - &(dlm_handles[3])); - lock_count = 4; - } - if (rc != ELDLM_OK) - GOTO(cleanup, rc); - - cleanup_phase = 6; /* child locks */ - - /* Step 4: Execute the rename */ - OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_RENAME_WRITE, - to_kdev_t(de_srcdir->d_inode->i_sb->s_dev)); - - handle = fsfilt_start(obd, de_tgtdir->d_inode, FSFILT_OP_RENAME); - if (IS_ERR(handle)) - GOTO(cleanup, rc = PTR_ERR(handle)); - - lock_kernel(); - rc = vfs_rename(de_srcdir->d_inode, de_old, de_tgtdir->d_inode, de_new, - NULL); - unlock_kernel(); - - EXIT; -cleanup: - rc = mds_finish_transno(mds, de_tgtdir ? de_tgtdir->d_inode : NULL, - handle, req, rc, 0); - switch (cleanup_phase) { - case 6: /* child locks */ - if (rc) { - ldlm_lock_decref(&(dlm_handles[2]), LCK_EX); - if (lock_count == 4) - ldlm_lock_decref(&(dlm_handles[3]), LCK_EX); - } else { - memcpy(&req->rq_ack_locks[2].lock, &(dlm_handles[2]), - sizeof(dlm_handles[2])); - req->rq_ack_locks[2].mode = LCK_EX; - if (lock_count == 4) { - memcpy(&req->rq_ack_locks[3].lock, - &dlm_handles[3], sizeof(dlm_handles[3])); - req->rq_ack_locks[3].mode = LCK_EX; - } - } - case 5: /* target dentry */ - l_dput(de_new); - case 4: /* source dentry */ - l_dput(de_old); - case 3: /* parent locks */ - if (rc) { - ldlm_lock_decref(&(dlm_handles[0]), LCK_EX); - ldlm_lock_decref(&(dlm_handles[1]), LCK_EX); - } else { - memcpy(&req->rq_ack_locks[0].lock, &(dlm_handles[0]), - sizeof(dlm_handles[0])); - memcpy(&req->rq_ack_locks[1].lock, &(dlm_handles[1]), - sizeof(dlm_handles[1])); - req->rq_ack_locks[0].mode = LCK_EX; - req->rq_ack_locks[1].mode = LCK_EX; - } - case 2: /* target directory dentry */ - l_dput(de_tgtdir); - case 1: /* source directry dentry */ - l_dput(de_srcdir); - case 0: - break; - default: - CERROR("invalid cleanup_phase %d\n", cleanup_phase); - LBUG(); - } - req->rq_status = rc; - return 0; -} - -typedef int (*mds_reinter)(struct mds_update_record *, int offset, - struct ptlrpc_request *, struct lustre_handle *); - -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, - [REINT_OPEN] mds_open -}; - -int mds_reint_rec(struct mds_update_record *rec, int offset, - struct ptlrpc_request *req, struct lustre_handle *lockh) -{ - struct mds_obd *mds = mds_req2mds(req); - struct obd_run_ctxt saved; - struct obd_ucred uc; - int realop = rec->ur_opcode & REINT_OPCODE_MASK, rc; - ENTRY; - - 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; - uc.ouc_suppgid1 = rec->ur_suppgid1; - uc.ouc_suppgid2 = rec->ur_suppgid2; - - push_ctxt(&saved, &mds->mds_ctxt, &uc); - rc = reinters[realop] (rec, offset, req, lockh); - 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 fb04cc1..0000000 --- a/lustre/obdclass/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ - -# FIXME: we need to make it clear that obdclass.o depends on -# lustre_build_version, or 'make -j2' breaks! -DEFS= -MODULE = obdclass - -if LINUX25 -FSMOD = fsfilt_ext3 -else -FSMOD = fsfilt_extN -endif - -if LIBLUSTRE -lib_LIBRARIES = liblustreclass.a -liblustreclass_a_SOURCES = uuid.c statfs_pack.c genops.c debug.c class_obd.c lustre_handles.c lustre_peer.c lprocfs_status.c - -class_obd.o: lustre_version - -lustre_version: - echo '#define LUSTRE_VERSION 12' > $(top_builddir)/include/linux/lustre_build_version.h - echo '#define BUILD_VERSION "1"' >> $(top_builddir)/include/linux/lustre_build_version.h - -else -modulefs_DATA = lustre_build_version obdclass.o $(FSMOD).o fsfilt_reiserfs.o -EXTRA_PROGRAMS = obdclass $(FSMOD) fsfilt_reiserfs - -obdclass_SOURCES = class_obd.c debug.c genops.c sysctl.c uuid.c lprocfs_status.c lustre_handles.c lustre_peer.c -obdclass_SOURCES += fsfilt.c statfs_pack.c -endif - -include $(top_srcdir)/Rules - -# XXX I'm sure there's some automake mv-if-different helper for this. -lustre_build_version: - perl $(top_srcdir)/scripts/version_tag.pl $(top_srcdir) $(top_builddir) > tmpver - cmp -z $(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 6200acd..0000000 --- a/lustre/obdclass/class_obd.c +++ /dev/null @@ -1,896 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Object Devices Class Driver - * - * Copyright (C) 2001-2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * These are the only exported functions, they provide some generic - * infrastructure for managing object devices - */ - -#define DEBUG_SUBSYSTEM S_CLASS -#define EXPORT_SYMTAB -#ifdef __KERNEL__ -#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 -#else - -# include - -#endif - -#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; -atomic_t obd_memory; -int obd_memmax; - -/* Root for /proc/lustre */ -struct proc_dir_entry *proc_lustre_root = NULL; - -/* 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"; -unsigned long obd_sync_filter; /* = 0, don't sync by default */ - -/* opening /dev/obd */ -static int obd_class_open(struct inode * inode, struct file * file) -{ - struct obd_class_user_state *ocus; - ENTRY; - - OBD_ALLOC (ocus, sizeof (*ocus)); - if (ocus == NULL) - return (-ENOMEM); - - INIT_LIST_HEAD (&ocus->ocus_conns); - ocus->ocus_current_obd = NULL; - file->private_data = ocus; - - MOD_INC_USE_COUNT; - RETURN(0); -} - -static int -obd_class_add_user_conn (struct obd_class_user_state *ocus, - struct lustre_handle *conn) -{ - struct obd_class_user_conn *c; - - /* NB holding obd_conf_sem */ - - OBD_ALLOC (c, sizeof (*c)); - if (ocus == NULL) - return (-ENOMEM); - - c->ocuc_conn = *conn; - list_add (&c->ocuc_chain, &ocus->ocus_conns); - return (0); -} - -static void -obd_class_remove_user_conn (struct obd_class_user_state *ocus, - struct lustre_handle *conn) -{ - struct list_head *e; - struct obd_class_user_conn *c; - - /* NB holding obd_conf_sem or last reference */ - - list_for_each (e, &ocus->ocus_conns) { - c = list_entry (e, struct obd_class_user_conn, ocuc_chain); - if (!memcmp (conn, &c->ocuc_conn, sizeof (*conn))) { - list_del (&c->ocuc_chain); - OBD_FREE (c, sizeof (*c)); - return; - } - } -} - -/* closing /dev/obd */ -static int obd_class_release(struct inode * inode, struct file * file) -{ - struct obd_class_user_state *ocus = file->private_data; - struct obd_class_user_conn *c; - ENTRY; - - while (!list_empty (&ocus->ocus_conns)) { - c = list_entry (ocus->ocus_conns.next, - struct obd_class_user_conn, ocuc_chain); - list_del (&c->ocuc_chain); - - CDEBUG (D_IOCTL, "Auto-disconnect %p\n", &c->ocuc_conn); - - down (&obd_conf_sem); - obd_disconnect (&c->ocuc_conn); - up (&obd_conf_sem); - - OBD_FREE (c, sizeof (*c)); - } - - OBD_FREE (ocus, sizeof (*ocus)); - - 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); - } - } -} - - -int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd, - unsigned long arg) -{ - char *buf = NULL; - struct obd_ioctl_data *data; - struct obd_device *obd = ocus->ocus_current_obd; - 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: - case ECHO_IOC_ENQUEUE: - case ECHO_IOC_CANCEL: - 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 && - cmd != OBD_IOC_ADD_UUID && cmd != OBD_IOC_DEL_UUID && - cmd != OBD_IOC_CLOSE_UUID) { - 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); - - ocus->ocus_current_obd = &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.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; - struct obd_uuid uuid; - - 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); - obd_str2uuid(&uuid, data->ioc_inlbuf1); - dev = class_uuid2dev(&uuid); - 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; - - ocus->ocus_current_obd = NULL; - for (i = 0 ; i < MAX_OBD_DEVICES ; i++) { - struct obd_device *obd = &obd_dev[i]; - if (!obd->obd_type) { - ocus->ocus_current_obd = 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, len; - - /* 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); - } - if (!data->ioc_inllen2 || !data->ioc_inlbuf2) { - CERROR("No name passed!\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_get_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); - - /* XXX belong ins setup not attach */ - /* recovery data */ - spin_lock_init(&obd->obd_processing_task_lock); - init_waitqueue_head(&obd->obd_next_transno_waitq); - INIT_LIST_HEAD(&obd->obd_recovery_queue); - INIT_LIST_HEAD(&obd->obd_delayed_reply_queue); - - len = strlen(data->ioc_inlbuf2) + 1; - OBD_ALLOC(obd->obd_name, len); - if (!obd->obd_name) { - class_put_type(obd->obd_type); - obd->obd_type = NULL; - GOTO(out, err = -ENOMEM); - } - memcpy(obd->obd_name, data->ioc_inlbuf2, len); - - if (data->ioc_inlbuf3) { - int len = strlen(data->ioc_inlbuf3); - if (len >= sizeof(obd->obd_uuid)) { - CERROR("uuid must be < "LPSZ" bytes long\n", - sizeof(obd->obd_uuid)); - if (obd->obd_name) - OBD_FREE(obd->obd_name, - strlen(obd->obd_name) + 1); - class_put_type(obd->obd_type); - obd->obd_type = NULL; - GOTO(out, err=-EINVAL); - } - memcpy(obd->obd_uuid.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); - class_put_type(obd->obd_type); - 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); - } - - 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 (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--; - class_put_type(obd->obd_type); - obd->obd_type = NULL; - 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 (!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 (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: { - struct obd_uuid 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 = obd_class_add_user_conn (ocus, &conn); - if (err != 0) { - obd_disconnect (&conn); - GOTO (out, err); - } - - err = copy_to_user((void *)arg, data, sizeof(*data)); - if (err != 0) { - obd_class_remove_user_conn (ocus, &conn); - obd_disconnect (&conn); - GOTO (out, err=-EFAULT); - } - GOTO(out, err); - } - - case OBD_IOC_DISCONNECT: { - obd_data2conn(&conn, data); - obd_class_remove_user_conn (ocus, &conn); - err = obd_disconnect(&conn); - GOTO(out, err); - } - - case OBD_IOC_NO_TRANSNO: { - if (!(obd->obd_flags & OBD_ATTACHED)) { - CERROR("Device %d not attached\n", obd->obd_minor); - GOTO(out, err=-ENODEV); - } - CDEBUG(D_IOCTL, - "disabling committed-transno notifications on %d\n", - obd->obd_minor); - obd->obd_flags |= OBD_NO_TRANSNO; - GOTO(out, err = 0); - } - - case OBD_IOC_CLOSE_UUID: { - struct lustre_peer peer; - CDEBUG(D_IOCTL, "closing all connections to uuid %s\n", - data->ioc_inlbuf1); - lustre_uuid_to_peer(data->ioc_inlbuf1, &peer); - GOTO(out, err = 0); - } - case OBD_IOC_ADD_UUID: { - CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64 - ", nal %d\n", data->ioc_inlbuf1, data->ioc_nid, - data->ioc_nal); - - err = class_add_uuid(data->ioc_inlbuf1, data->ioc_nid, - data->ioc_nal); - GOTO(out, err); - } - case OBD_IOC_DEL_UUID: { - CDEBUG(D_IOCTL, "removing mappings for uuid %s\n", - data->ioc_inlbuf1 == NULL ? "" : - data->ioc_inlbuf1); - - err = class_del_uuid(data->ioc_inlbuf1); - GOTO(out, err); - } - default: { - // obd_data2conn(&conn, data); - struct obd_class_user_conn *oconn = list_entry(ocus->ocus_conns.next, struct obd_class_user_conn, ocuc_chain); - err = obd_iocontrol(cmd, &oconn->ocuc_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 */ - - - -#define OBD_MINOR 241 -#ifdef __KERNEL__ -/* to control /dev/obd */ -static int obd_class_ioctl (struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long arg) -{ - return class_handle_ioctl(filp->private_data, cmd, arg); -} - -/* 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 */ -static struct miscdevice obd_psdev = { - OBD_MINOR, - "obd_psdev", - &obd_psdev_fops -}; -#else -void *obd_psdev = NULL; -#endif - -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_memmax); -EXPORT_SYMBOL(obd_fail_loc); -EXPORT_SYMBOL(obd_timeout); -EXPORT_SYMBOL(obd_recovery_upcall); -EXPORT_SYMBOL(obd_sync_filter); -EXPORT_SYMBOL(ptlrpc_put_connection_superhack); -EXPORT_SYMBOL(ptlrpc_abort_inflight_superhack); -EXPORT_SYMBOL(proc_lustre_root); - -EXPORT_SYMBOL(class_register_type); -EXPORT_SYMBOL(class_unregister_type); -EXPORT_SYMBOL(class_get_type); -EXPORT_SYMBOL(class_put_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(lustre_uuid_to_peer); - -EXPORT_SYMBOL(class_signal_connection_failure); - -EXPORT_SYMBOL(class_handle_hash); -EXPORT_SYMBOL(class_handle_unhash); -EXPORT_SYMBOL(class_handle2object); - -#ifdef __KERNEL__ -static int __init init_obdclass(void) -#else -int init_obdclass(void) -#endif -{ - struct obd_device *obd; - int err; - int i; - - printk(KERN_INFO "OBD class driver Build Version: " BUILD_VERSION - ", info@clusterfs.com\n"); - - class_init_uuidlist(); - class_handle_init(); - - 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; - -#ifdef __KERNEL__ - obd_sysctl_init(); -#endif - -#ifdef LPROCFS - proc_lustre_root = proc_mkdir("lustre", proc_root_fs); - if (!proc_lustre_root) - printk(KERN_ERR "error registering /proc/fs/lustre\n"); -#else - proc_lustre_root = NULL; -#endif - return 0; -} - -#ifdef __KERNEL__ -static void __exit cleanup_obdclass(void) -#else -static void cleanup_obdclass(void) -#endif -{ - int i; - 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(); -#ifdef __KERNEL__ - obd_sysctl_clean(); -#endif - if (proc_lustre_root) { - lprocfs_remove(proc_lustre_root); - proc_lustre_root = NULL; - } - - class_handle_cleanup(); - class_exit_uuidlist(); - - CERROR("obd mem max: %d leaked: %d\n", obd_memmax, - atomic_read(&obd_memory)); - EXIT; -} - -/* Check that we're building against the appropriate version of the Lustre - * kernel patch */ -#ifdef __KERNEL__ -#include -#define LUSTRE_SOURCE_VERSION 13 -#if (LUSTRE_KERNEL_VERSION < LUSTRE_SOURCE_VERSION) -# error Cannot continue: Your Lustre kernel patch is older than the sources -#elif (LUSTRE_KERNEL_VERSION > LUSTRE_SOURCE_VERSION) -# error Cannot continue: Your Lustre sources are older than the kernel patch -#endif -#else -#warning "Lib Lustre - no versioning information" -#endif - -#ifdef __KERNEL__ -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); -#endif diff --git a/lustre/obdclass/debug.c b/lustre/obdclass/debug.c deleted file mode 100644 index 6118084..0000000 --- a/lustre/obdclass/debug.c +++ /dev/null @@ -1,161 +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 -#ifndef __KERNEL__ -#include -#endif - -#include -#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/fsfilt.c b/lustre/obdclass/fsfilt.c deleted file mode 100644 index 07ce0b3..0000000 --- a/lustre/obdclass/fsfilt.c +++ /dev/null @@ -1,107 +0,0 @@ -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_FILTER - -#include -#include -#include -#include -#include -#include -#include - -LIST_HEAD(fsfilt_types); - -static struct fsfilt_operations *fsfilt_search_type(const char *type) -{ - struct fsfilt_operations *found; - struct list_head *p; - - list_for_each(p, &fsfilt_types) { - found = list_entry(p, struct fsfilt_operations, fs_list); - if (!strcmp(found->fs_type, type)) { - return found; - } - } - return NULL; -} - -int fsfilt_register_ops(struct fsfilt_operations *fs_ops) -{ - struct fsfilt_operations *found; - - /* lock fsfilt_types list */ - if ((found = fsfilt_search_type(fs_ops->fs_type))) { - if (found != fs_ops) { - CERROR("different operations for type %s\n", - fs_ops->fs_type); - /* unlock fsfilt_types list */ - RETURN(-EEXIST); - } - } else { - MOD_INC_USE_COUNT; - list_add(&fs_ops->fs_list, &fsfilt_types); - } - - /* unlock fsfilt_types list */ - return 0; -} - -void fsfilt_unregister_ops(struct fsfilt_operations *fs_ops) -{ - struct list_head *p; - - /* lock fsfilt_types list */ - list_for_each(p, &fsfilt_types) { - struct fsfilt_operations *found; - - found = list_entry(p, typeof(*found), fs_list); - if (found == fs_ops) { - list_del(p); - MOD_DEC_USE_COUNT; - break; - } - } - /* unlock fsfilt_types list */ -} - -struct fsfilt_operations *fsfilt_get_ops(char *type) -{ - struct fsfilt_operations *fs_ops; - - /* lock fsfilt_types list */ - if (!(fs_ops = fsfilt_search_type(type))) { - char name[32]; - int rc; - - snprintf(name, sizeof(name) - 1, "fsfilt_%s", type); - name[sizeof(name) - 1] = '\0'; - - if ((rc = request_module(name))) { - fs_ops = fsfilt_search_type(type); - CDEBUG(D_INFO, "Loaded module '%s'\n", name); - if (!fs_ops) - rc = -ENOENT; - } - - if (rc) { - CERROR("Can't find fsfilt_%s interface\n", name); - RETURN(ERR_PTR(rc)); - /* unlock fsfilt_types list */ - } - } - __MOD_INC_USE_COUNT(fs_ops->fs_owner); - /* unlock fsfilt_types list */ - - return fs_ops; -} - -void fsfilt_put_ops(struct fsfilt_operations *fs_ops) -{ - __MOD_DEC_USE_COUNT(fs_ops->fs_owner); -} - - -EXPORT_SYMBOL(fsfilt_register_ops); -EXPORT_SYMBOL(fsfilt_unregister_ops); -EXPORT_SYMBOL(fsfilt_get_ops); -EXPORT_SYMBOL(fsfilt_put_ops); diff --git a/lustre/obdclass/fsfilt_ext3.c b/lustre/obdclass/fsfilt_ext3.c deleted file mode 100644 index 72f2830..0000000 --- a/lustre/obdclass/fsfilt_ext3.c +++ /dev/null @@ -1,340 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/lib/fsfilt_ext3.c - * Lustre filesystem abstraction routines - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Andreas Dilger - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -//#error "FIXME: this needs to be updated to match fsfilt_extN.c" - -#define DEBUG_SUBSYSTEM S_FILTER - -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -# include -#else -# include -#endif -#include -#include -#include -#include - -static kmem_cache_t *fcb_cache; -static atomic_t fcb_cache_count = ATOMIC_INIT(0); - -struct fsfilt_cb_data { - struct journal_callback cb_jcb; /* data private to jbd */ - fsfilt_cb_t cb_func; /* MDS/OBD completion function */ - struct obd_device *cb_obd; /* MDS/OBD completion device */ - __u64 cb_last_rcvd; /* MDS/OST last committed operation */ -}; - -#define EXT3_XATTR_INDEX_LUSTRE 5 -#define XATTR_LUSTRE_MDS_OBJID "system.lustre_mds_objid" - -/* - * We don't currently need any additional blocks for rmdir and - * unlink transactions because we are storing the OST oa_id inside - * the inode (which we will be changing anyways as part of this - * transaction). - */ -static void *fsfilt_ext3_start(struct inode *inode, int op) -{ - /* For updates to the last recieved file */ - int nblocks = EXT3_DATA_TRANS_BLOCKS; - void *handle; - - switch(op) { - case FSFILT_OP_RMDIR: - case FSFILT_OP_UNLINK: - nblocks += EXT3_DELETE_TRANS_BLOCKS; - break; - case FSFILT_OP_RENAME: - /* We may be modifying two directories */ - nblocks += EXT3_DATA_TRANS_BLOCKS; - case FSFILT_OP_SYMLINK: - /* Possible new block + block bitmap + GDT for long symlink */ - nblocks += 3; - case FSFILT_OP_CREATE: - case FSFILT_OP_MKDIR: - case FSFILT_OP_MKNOD: - /* New inode + block bitmap + GDT for new file */ - nblocks += 3; - case FSFILT_OP_LINK: - /* Change parent directory */ - nblocks += EXT3_INDEX_EXTRA_TRANS_BLOCKS+EXT3_DATA_TRANS_BLOCKS; - break; - case FSFILT_OP_SETATTR: - /* Setattr on inode */ - nblocks += 1; - break; - default: CERROR("unknown transaction start op %d\n", op); - LBUG(); - } - - lock_kernel(); - handle = journal_start(EXT3_JOURNAL(inode), nblocks); - unlock_kernel(); - - return handle; -} - -static int fsfilt_ext3_commit(struct inode *inode, void *handle) -{ - int rc; - - lock_kernel(); - rc = journal_stop((handle_t *)handle); - unlock_kernel(); - - return rc; -} - -static int fsfilt_ext3_setattr(struct dentry *dentry, void *handle, - struct iattr *iattr) -{ - struct inode *inode = dentry->d_inode; - int rc; - - lock_kernel(); - if (inode->i_op->setattr) - rc = inode->i_op->setattr(dentry, iattr); - else - rc = inode_setattr(inode, iattr); - - unlock_kernel(); - - return rc; -} - -static int fsfilt_ext3_set_md(struct inode *inode, void *handle, - void *lmm, int lmm_size) -{ - int rc; - - down(&inode->i_sem); - lock_kernel(); - rc = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_LUSTRE, - XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size, 0); - unlock_kernel(); - up(&inode->i_sem); - - if (rc) { - CERROR("error adding MD data to inode %lu: rc = %d\n", - inode->i_ino, rc); - if (rc != -ENOSPC) LBUG(); - } - return rc; -} - -static int fsfilt_ext3_get_md(struct inode *inode, void *lmm, int size) -{ - int rc; - - down(&inode->i_sem); - lock_kernel(); - rc = ext3_xattr_get(inode, EXT3_XATTR_INDEX_LUSTRE, - XATTR_LUSTRE_MDS_OBJID, lmm, size); - unlock_kernel(); - up(&inode->i_sem); - - /* This gives us the MD size */ - if (lmm == NULL) - return (rc == -ENODATA) ? 0 : rc; - - if (rc < 0) { - CDEBUG(D_INFO, "error getting EA %s from inode %lu: " - "rc = %d\n", XATTR_LUSTRE_MDS_OBJID, inode->i_ino, rc); - memset(lmm, 0, size); - return (rc == -ENODATA) ? 0 : rc; - } - - return rc; -} - -static ssize_t fsfilt_ext3_readpage(struct file *file, char *buf, size_t count, - loff_t *offset) -{ - struct inode *inode = file->f_dentry->d_inode; - int rc = 0; - - if (S_ISREG(inode->i_mode)) - rc = file->f_op->read(file, buf, count, offset); - else { - struct buffer_head *bh; - - /* FIXME: this assumes the blocksize == count, but the calling - * function will detect this as an error for now */ - bh = ext3_bread(NULL, inode, - *offset >> inode->i_sb->s_blocksize_bits, - 0, &rc); - - if (bh) { - memcpy(buf, bh->b_data, inode->i_blksize); - brelse(bh); - rc = inode->i_blksize; - } - } - - return rc; -} - -static void fsfilt_ext3_cb_func(struct journal_callback *jcb, int error) -{ - struct fsfilt_cb_data *fcb = (struct fsfilt_cb_data *)jcb; - - fcb->cb_func(fcb->cb_obd, fcb->cb_last_rcvd, error); - - kmem_cache_free(fcb_cache, fcb); - atomic_dec(&fcb_cache_count); -} - -static int fsfilt_ext3_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func) -{ -#ifdef HAVE_JOURNAL_CALLBACK_STATUS - struct fsfilt_cb_data *fcb; - - fcb = kmem_cache_alloc(fcb_cache, GFP_NOFS); - if (!fcb) - RETURN(-ENOMEM); - - atomic_inc(&fcb_cache_count); - fcb->cb_func = cb_func; - fcb->cb_obd = obd; - fcb->cb_last_rcvd = last_rcvd; - - CDEBUG(D_EXT2, "set callback for last_rcvd: "LPD64"\n", last_rcvd); - lock_kernel(); - /* Note that an "incompatible pointer" warning here is OK for now */ - journal_callback_set(handle, fsfilt_ext3_cb_func, - (struct journal_callback *)fcb); - unlock_kernel(); -#else -#warning "no journal callback kernel patch, faking it..." - static long next = 0; - - if (time_after(jiffies, next)) { - CERROR("no journal callback kernel patch, faking it...\n"); - next = jiffies + 300 * HZ; - } - - cb_func(obd, last_rcvd, 0); -#endif - - return 0; -} - -static int fsfilt_ext3_journal_data(struct file *filp) -{ - struct inode *inode = filp->f_dentry->d_inode; - - EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL; - - return 0; -} - -/* - * We need to hack the return value for the free inode counts because - * the current EA code requires one filesystem block per inode with EAs, - * so it is possible to run out of blocks before we run out of inodes. - * - * This can be removed when the ext3 EA code is fixed. - */ -static int fsfilt_ext3_statfs(struct super_block *sb, struct statfs *sfs) -{ - int rc = vfs_statfs(sb, sfs); - - if (!rc && sfs->f_bfree < sfs->f_ffree) - sfs->f_ffree = sfs->f_bfree; - - return rc; -} - -static int fsfilt_ext3_sync(struct super_block *sb) -{ - return ext3_force_commit(sb); -} - -static struct fsfilt_operations fsfilt_ext3_ops = { - fs_type: "ext3", - fs_owner: THIS_MODULE, - fs_start: fsfilt_ext3_start, - fs_commit: fsfilt_ext3_commit, - fs_setattr: fsfilt_ext3_setattr, - fs_set_md: fsfilt_ext3_set_md, - fs_get_md: fsfilt_ext3_get_md, - fs_readpage: fsfilt_ext3_readpage, - fs_journal_data: fsfilt_ext3_journal_data, - fs_set_last_rcvd: fsfilt_ext3_set_last_rcvd, - fs_statfs: fsfilt_ext3_statfs, - fs_sync: fsfilt_ext3_sync, -}; - -static int __init fsfilt_ext3_init(void) -{ - int rc; - - //rc = ext3_xattr_register(); - fcb_cache = kmem_cache_create("fsfilt_ext3_fcb", - sizeof(struct fsfilt_cb_data), 0, - 0, NULL, NULL); - if (!fcb_cache) { - CERROR("error allocating fsfilt journal callback cache\n"); - GOTO(out, rc = -ENOMEM); - } - - rc = fsfilt_register_ops(&fsfilt_ext3_ops); - - if (rc) - kmem_cache_destroy(fcb_cache); -out: - return rc; -} - -static void __exit fsfilt_ext3_exit(void) -{ - int rc; - - fsfilt_unregister_ops(&fsfilt_ext3_ops); - rc = kmem_cache_destroy(fcb_cache); - - if (rc || atomic_read(&fcb_cache_count)) { - CERROR("can't free fsfilt callback cache: count %d, rc = %d\n", - atomic_read(&fcb_cache_count), rc); - } - - //rc = ext3_xattr_unregister(); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre ext3 Filesystem Helper v0.1"); -MODULE_LICENSE("GPL"); - -module_init(fsfilt_ext3_init); -module_exit(fsfilt_ext3_exit); diff --git a/lustre/obdclass/fsfilt_extN.c b/lustre/obdclass/fsfilt_extN.c deleted file mode 100644 index d029785..0000000 --- a/lustre/obdclass/fsfilt_extN.c +++ /dev/null @@ -1,547 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/lib/fsfilt_extN.c - * Lustre filesystem abstraction routines - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * Author: Andreas Dilger - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define DEBUG_SUBSYSTEM S_FILTER - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static kmem_cache_t *fcb_cache; -static atomic_t fcb_cache_count = ATOMIC_INIT(0); - -struct fsfilt_cb_data { - struct journal_callback cb_jcb; /* data private to jbd */ - fsfilt_cb_t cb_func; /* MDS/OBD completion function */ - struct obd_device *cb_obd; /* MDS/OBD completion device */ - __u64 cb_last_rcvd; /* MDS/OST last committed operation */ -}; - -#define EXTN_XATTR_INDEX_LUSTRE 5 -#define XATTR_LUSTRE_MDS_OBJID "system.lustre_mds_objid" - -/* - * We don't currently need any additional blocks for rmdir and - * unlink transactions because we are storing the OST oa_id inside - * the inode (which we will be changing anyways as part of this - * transaction). - */ -static void *fsfilt_extN_start(struct inode *inode, int op) -{ - /* For updates to the last recieved file */ - int nblocks = EXTN_DATA_TRANS_BLOCKS; - void *handle; - - switch(op) { - case FSFILT_OP_RMDIR: - case FSFILT_OP_UNLINK: - nblocks += EXTN_DELETE_TRANS_BLOCKS; - break; - case FSFILT_OP_RENAME: - /* modify additional directory */ - nblocks += EXTN_DATA_TRANS_BLOCKS; - /* no break */ - case FSFILT_OP_SYMLINK: - /* additional block + block bitmap + GDT for long symlink */ - nblocks += 3; - /* no break */ - case FSFILT_OP_CREATE: - case FSFILT_OP_MKDIR: - case FSFILT_OP_MKNOD: - /* modify one inode + block bitmap + GDT */ - nblocks += 3; - /* no break */ - case FSFILT_OP_LINK: - /* modify parent directory */ - nblocks += EXTN_INDEX_EXTRA_TRANS_BLOCKS+EXTN_DATA_TRANS_BLOCKS; - break; - case FSFILT_OP_SETATTR: - /* Setattr on inode */ - nblocks += 1; - break; - default: CERROR("unknown transaction start op %d\n", op); - LBUG(); - } - - LASSERT(!current->journal_info); - lock_kernel(); - handle = journal_start(EXTN_JOURNAL(inode), nblocks); - unlock_kernel(); - - return handle; -} - -/* - * Calculate the number of buffer credits needed to write multiple pages in - * a single extN transaction. No, this shouldn't be here, but as yet extN - * doesn't have a nice API for calculating this sort of thing in advance. - * - * See comment above extN_writepage_trans_blocks for details. We assume - * no data journaling is being done, but it does allow for all of the pages - * being non-contiguous. If we are guaranteed contiguous pages we could - * reduce the number of (d)indirect blocks a lot. - * - * With N blocks per page and P pages, for each inode we have at most: - * N*P indirect - * min(N*P, blocksize/4 + 1) dindirect blocks - * niocount tindirect - * - * For the entire filesystem, we have at most: - * min(sum(nindir + P), ngroups) bitmap blocks (from the above) - * min(sum(nindir + P), gdblocks) group descriptor blocks (from the above) - * objcount inode blocks - * 1 superblock - * 2 * EXTN_SINGLEDATA_TRANS_BLOCKS for the quota files - * - * 1 EXTN_DATA_TRANS_BLOCKS for the last_rcvd update. - */ -static int fsfilt_extN_credits_needed(int objcount, struct fsfilt_objinfo *fso) -{ - struct super_block *sb = fso->fso_dentry->d_inode->i_sb; - int blockpp = 1 << (PAGE_CACHE_SHIFT - sb->s_blocksize_bits); - int addrpp = EXTN_ADDR_PER_BLOCK(sb) * blockpp; - int nbitmaps = 0; - int ngdblocks = 0; - int needed = objcount + 1; - int i; - - for (i = 0; i < objcount; i++, fso++) { - int nblocks = fso->fso_bufcnt * blockpp; - int ndindirect = min(nblocks, addrpp + 1); - int nindir = nblocks + ndindirect + 1; - - nbitmaps += nindir + nblocks; - ngdblocks += nindir + nblocks; - - needed += nindir; - } - - /* Assumes extN and extN have same sb_info layout at the start. */ - if (nbitmaps > EXTN_SB(sb)->s_groups_count) - nbitmaps = EXTN_SB(sb)->s_groups_count; - if (ngdblocks > EXTN_SB(sb)->s_gdb_count) - ngdblocks = EXTN_SB(sb)->s_gdb_count; - - needed += nbitmaps + ngdblocks; - - /* last_rcvd update */ - needed += EXTN_DATA_TRANS_BLOCKS; - -#ifdef CONFIG_QUOTA - /* We assume that there will be 1 bit set in s_dquot.flags for each - * quota file that is active. This is at least true for now. - */ - needed += hweight32(sb_any_quota_enabled(sb)) * - EXTN_SINGLEDATA_TRANS_BLOCKS; -#endif - - return needed; -} - -/* We have to start a huge journal transaction here to hold all of the - * metadata for the pages being written here. This is necessitated by - * the fact that we do lots of prepare_write operations before we do - * any of the matching commit_write operations, so even if we split - * up to use "smaller" transactions none of them could complete until - * all of them were opened. By having a single journal transaction, - * we eliminate duplicate reservations for common blocks like the - * superblock and group descriptors or bitmaps. - * - * We will start the transaction here, but each prepare_write will - * add a refcount to the transaction, and each commit_write will - * remove a refcount. The transaction will be closed when all of - * the pages have been written. - */ -static void *fsfilt_extN_brw_start(int objcount, struct fsfilt_objinfo *fso, - int niocount, struct niobuf_remote *nb) -{ - journal_t *journal; - handle_t *handle; - int needed; - ENTRY; - - LASSERT(!current->journal_info); - journal = EXTN_SB(fso->fso_dentry->d_inode->i_sb)->s_journal; - needed = fsfilt_extN_credits_needed(objcount, fso); - - /* The number of blocks we could _possibly_ dirty can very large. - * We reduce our request if it is absurd (and we couldn't get that - * many credits for a single handle anyways). - * - * At some point we have to limit the size of I/Os sent at one time, - * increase the size of the journal, or we have to calculate the - * actual journal requirements more carefully by checking all of - * the blocks instead of being maximally pessimistic. It remains to - * be seen if this is a real problem or not. - */ - if (needed > journal->j_max_transaction_buffers) { - CERROR("want too many journal credits (%d) using %d instead\n", - needed, journal->j_max_transaction_buffers); - needed = journal->j_max_transaction_buffers; - } - - lock_kernel(); - handle = journal_start(journal, needed); - unlock_kernel(); - if (IS_ERR(handle)) - CERROR("can't get handle for %d credits: rc = %ld\n", needed, - PTR_ERR(handle)); - - RETURN(handle); -} - -static int fsfilt_extN_commit(struct inode *inode, void *h /*, force_sync */) -{ - int rc; - handle_t *handle = h; - -#if 0 - if (force_sync) - handle->h_sync = 1; /* recovery likes this */ -#endif - - lock_kernel(); - rc = journal_stop(handle); - unlock_kernel(); - - return rc; -} - -static int fsfilt_extN_setattr(struct dentry *dentry, void *handle, - struct iattr *iattr) -{ - struct inode *inode = dentry->d_inode; - int rc; - - lock_kernel(); - - /* A _really_ horrible hack to avoid removing the data stored - * in the block pointers; this is really the "small" stripe MD data. - * We can avoid further hackery by virtue of the MDS file size being - * zero all the time (which doesn't invoke block truncate at unlink - * time), so we assert we never change the MDS file size from zero. - */ - if (iattr->ia_valid & ATTR_SIZE) { - CERROR("hmm, setting %*s file size to %lld\n", - dentry->d_name.len, dentry->d_name.name, iattr->ia_size); - LASSERT(iattr->ia_size == 0); -#if 0 - /* 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; - } -#endif - } - if (inode->i_op->setattr) - rc = inode->i_op->setattr(dentry, iattr); - else - rc = inode_setattr(inode, iattr); - - unlock_kernel(); - - return rc; -} - -static int fsfilt_extN_set_md(struct inode *inode, void *handle, - void *lmm, int lmm_size) -{ - int rc; - - /* Nasty hack city - store stripe MD data in the block pointers if - * it will fit, because putting it in an EA currently kills the MDS - * performance. We'll fix this with "fast EAs" in the future. - */ - if (lmm_size <= sizeof(EXTN_I(inode)->i_data) - - sizeof(EXTN_I(inode)->i_data[0])) { - /* XXX old_size is debugging only */ - int old_size = EXTN_I(inode)->i_data[0]; - if (old_size != 0) { - LASSERT(old_size < sizeof(EXTN_I(inode)->i_data)); - CERROR("setting EA on %lu again... interesting\n", - inode->i_ino); - } - - EXTN_I(inode)->i_data[0] = cpu_to_le32(lmm_size); - memcpy(&EXTN_I(inode)->i_data[1], lmm, lmm_size); - mark_inode_dirty(inode); - return 0; - } else { - down(&inode->i_sem); - lock_kernel(); - rc = extN_xattr_set(handle, inode, EXTN_XATTR_INDEX_LUSTRE, - XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size, 0); - unlock_kernel(); - up(&inode->i_sem); - } - - if (rc) - CERROR("error adding MD data to inode %lu: rc = %d\n", - inode->i_ino, rc); - return rc; -} - -static int fsfilt_extN_get_md(struct inode *inode, void *lmm, int lmm_size) -{ - int rc; - - if (EXTN_I(inode)->i_data[0]) { - int size = le32_to_cpu(EXTN_I(inode)->i_data[0]); - LASSERT(size < sizeof(EXTN_I(inode)->i_data)); - if (lmm) { - if (size > lmm_size) - return -ERANGE; - memcpy(lmm, &EXTN_I(inode)->i_data[1], size); - } - return size; - } - - down(&inode->i_sem); - lock_kernel(); - rc = extN_xattr_get(inode, EXTN_XATTR_INDEX_LUSTRE, - XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size); - unlock_kernel(); - up(&inode->i_sem); - - /* This gives us the MD size */ - if (lmm == NULL) - return (rc == -ENODATA) ? 0 : rc; - - if (rc < 0) { - CDEBUG(D_INFO, "error getting EA %s from inode %lu: " - "rc = %d\n", XATTR_LUSTRE_MDS_OBJID, inode->i_ino, rc); - memset(lmm, 0, lmm_size); - return (rc == -ENODATA) ? 0 : rc; - } - - return rc; -} - -static ssize_t fsfilt_extN_readpage(struct file *file, char *buf, size_t count, - loff_t *off) -{ - 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, off); - else { - const int blkbits = inode->i_sb->s_blocksize_bits; - const int blksize = inode->i_sb->s_blocksize; - - CDEBUG(D_EXT2, "reading "LPSZ" at dir %lu+%llu\n", - count, inode->i_ino, *off); - while (count > 0) { - struct buffer_head *bh; - - bh = NULL; - if (*off < inode->i_size) { - int err = 0; - - bh = extN_bread(NULL, inode, *off >> blkbits, - 0, &err); - - CDEBUG(D_EXT2, "read %u@%llu\n", blksize, *off); - - if (bh) { - memcpy(buf, bh->b_data, blksize); - brelse(bh); - } else if (err) { - /* XXX in theory we should just fake - * this buffer and continue like ext3, - * especially if this is a partial read - */ - CERROR("error read dir %lu+%llu: %d\n", - inode->i_ino, *off, err); - RETURN(err); - } - } - if (!bh) { - struct extN_dir_entry_2 *fake = (void *)buf; - - CDEBUG(D_EXT2, "fake %u@%llu\n", blksize, *off); - memset(fake, 0, sizeof(*fake)); - fake->rec_len = cpu_to_le32(blksize); - } - count -= blksize; - buf += blksize; - *off += blksize; - rc += blksize; - } - } - - return rc; -} - -static void fsfilt_extN_cb_func(struct journal_callback *jcb, int error) -{ - struct fsfilt_cb_data *fcb = (struct fsfilt_cb_data *)jcb; - - fcb->cb_func(fcb->cb_obd, fcb->cb_last_rcvd, error); - - kmem_cache_free(fcb_cache, fcb); - atomic_dec(&fcb_cache_count); -} - -static int fsfilt_extN_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func) -{ - struct fsfilt_cb_data *fcb; - - fcb = kmem_cache_alloc(fcb_cache, GFP_NOFS); - if (!fcb) - RETURN(-ENOMEM); - - atomic_inc(&fcb_cache_count); - fcb->cb_func = cb_func; - fcb->cb_obd = obd; - fcb->cb_last_rcvd = last_rcvd; - - CDEBUG(D_EXT2, "set callback for last_rcvd: "LPD64"\n", last_rcvd); - lock_kernel(); - /* Note that an "incompatible pointer" warning here is OK for now */ - journal_callback_set(handle, fsfilt_extN_cb_func, - (struct journal_callback *)fcb); - unlock_kernel(); - - return 0; -} - -static int fsfilt_extN_journal_data(struct file *filp) -{ - struct inode *inode = filp->f_dentry->d_inode; - - EXTN_I(inode)->i_flags |= EXTN_JOURNAL_DATA_FL; - - return 0; -} - -/* - * We need to hack the return value for the free inode counts because - * the current EA code requires one filesystem block per inode with EAs, - * so it is possible to run out of blocks before we run out of inodes. - * - * This can be removed when the extN EA code is fixed. - */ -static int fsfilt_extN_statfs(struct super_block *sb, struct obd_statfs *osfs) -{ - struct statfs sfs; - int rc = vfs_statfs(sb, &sfs); - - if (!rc && sfs.f_bfree < sfs.f_ffree) - sfs.f_ffree = sfs.f_bfree; - - statfs_pack(osfs, &sfs); - return rc; -} - -static int fsfilt_extN_sync(struct super_block *sb) -{ - return extN_force_commit(sb); -} - -extern int extN_prep_san_write(struct inode *inode, long *blocks, - int nblocks, loff_t newsize); -static int fsfilt_extN_prep_san_write(struct inode *inode, long *blocks, - int nblocks, loff_t newsize) -{ - return extN_prep_san_write(inode, blocks, nblocks, newsize); -} - -static struct fsfilt_operations fsfilt_extN_ops = { - fs_type: "extN", - fs_owner: THIS_MODULE, - fs_start: fsfilt_extN_start, - fs_brw_start: fsfilt_extN_brw_start, - fs_commit: fsfilt_extN_commit, - fs_setattr: fsfilt_extN_setattr, - fs_set_md: fsfilt_extN_set_md, - fs_get_md: fsfilt_extN_get_md, - fs_readpage: fsfilt_extN_readpage, - fs_journal_data: fsfilt_extN_journal_data, - fs_set_last_rcvd: fsfilt_extN_set_last_rcvd, - fs_statfs: fsfilt_extN_statfs, - fs_sync: fsfilt_extN_sync, - fs_prep_san_write: fsfilt_extN_prep_san_write, -}; - -static int __init fsfilt_extN_init(void) -{ - int rc; - - //rc = extN_xattr_register(); - fcb_cache = kmem_cache_create("fsfilt_extN_fcb", - sizeof(struct fsfilt_cb_data), 0, - 0, NULL, NULL); - if (!fcb_cache) { - CERROR("error allocating fsfilt journal callback cache\n"); - GOTO(out, rc = -ENOMEM); - } - - rc = fsfilt_register_ops(&fsfilt_extN_ops); - - if (rc) - kmem_cache_destroy(fcb_cache); -out: - return rc; -} - -static void __exit fsfilt_extN_exit(void) -{ - int rc; - - fsfilt_unregister_ops(&fsfilt_extN_ops); - rc = kmem_cache_destroy(fcb_cache); - - if (rc || atomic_read(&fcb_cache_count)) { - CERROR("can't free fsfilt callback cache: count %d, rc = %d\n", - atomic_read(&fcb_cache_count), rc); - } - - //rc = extN_xattr_unregister(); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre extN Filesystem Helper v0.1"); -MODULE_LICENSE("GPL"); - -module_init(fsfilt_extN_init); -module_exit(fsfilt_extN_exit); diff --git a/lustre/obdclass/fsfilt_reiserfs.c b/lustre/obdclass/fsfilt_reiserfs.c deleted file mode 100644 index 06302c5..0000000 --- a/lustre/obdclass/fsfilt_reiserfs.c +++ /dev/null @@ -1,205 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/lib/fsfilt_reiserfs.c - * Lustre filesystem abstraction routines - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Andreas Dilger - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * NOTE - According to Hans Reiser, this could actually be implemented more - * efficiently than creating a directory and putting ASCII objids in it. - * Instead, we should return the reiserfs object ID as the lustre objid - * (although I'm not sure what impact that would have on backup/restore). - */ - -#define DEBUG_SUBSYSTEM S_FILTER - -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -#include -#include -#endif -#include -#include -#include -#include -#include - -static void *fsfilt_reiserfs_start(struct inode *inode, int op) -{ - return (void *)0xf00f00be; -} - -static void *fsfilt_reiserfs_brw_start(int objcount, struct fsfilt_objinfo *fso, - int niocount, struct niobuf_remote *nb) -{ - return (void *)0xf00f00be; -} - -static int fsfilt_reiserfs_commit(struct inode *inode, void *handle) -{ - if (handle != (void *)0xf00f00be) { - CERROR("bad handle %p", handle); - return -EINVAL; - } - - return 0; -} - -static int fsfilt_reiserfs_setattr(struct dentry *dentry, void *handle, - struct iattr *iattr) -{ - struct inode *inode = dentry->d_inode; - int rc; - - lock_kernel(); - - /* A _really_ horrible hack to avoid removing the data stored - * in the block pointers; this is really the "small" stripe MD data. - * We can avoid further hackery by virtue of the MDS file size being - * zero all the time (which doesn't invoke block truncate at unlink - * time), so we assert we never change the MDS file size from zero. - */ - if (iattr->ia_valid & ATTR_SIZE) { - CERROR("hmm, setting %*s file size to %llu\n", - dentry->d_name.len, dentry->d_name.name, iattr->ia_size); - LASSERT(iattr->ia_size == 0); -#if 0 - /* 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; - } -#endif - } - if (inode->i_op->setattr) - rc = inode->i_op->setattr(dentry, iattr); - else - rc = inode_setattr(inode, iattr); - - unlock_kernel(); - - return rc; -} - -static int fsfilt_reiserfs_set_md(struct inode *inode, void *handle, - void *lmm, int lmm_size) -{ - /* XXX write stripe data into MDS file itself */ - CERROR("not implemented yet\n"); - - return -ENOSYS; -} - -static int fsfilt_reiserfs_get_md(struct inode *inode, void *lmm, int lmm_size) -{ - if (lmm == NULL) - return inode->i_size; - - CERROR("not implemented yet\n"); - return -ENOSYS; -} - -static ssize_t fsfilt_reiserfs_readpage(struct file *file, char *buf, size_t count, - loff_t *offset) -{ - return file->f_op->read(file, buf, count, offset); -} - -static int fsfilt_reiserfs_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func) -{ - static long next = 0; - - if (time_after(jiffies, next)) { - CERROR("no journal callback kernel patch, faking it...\n"); - next = jiffies + 300 * HZ; - } - - cb_func(obd, last_rcvd, 0); - - return 0; -} - -static int fsfilt_reiserfs_journal_data(struct file *filp) -{ - CERROR("not implemented yet\n"); - return 0; -} - -static int fsfilt_reiserfs_statfs(struct super_block *sb, struct obd_statfs *osfs) -{ - struct statfs sfs; - int rc = vfs_statfs(sb, &sfs); - - statfs_pack(osfs, &sfs); - return rc; -} - -static int fsfilt_reiserfs_sync(struct super_block *sb) -{ - CERROR("not implemented yet\n"); - return -ENOSYS; -} - -static struct fsfilt_operations fsfilt_reiserfs_ops = { - fs_type: "reiserfs", - fs_owner: THIS_MODULE, - fs_start: fsfilt_reiserfs_start, - fs_brw_start: fsfilt_reiserfs_brw_start, - fs_commit: fsfilt_reiserfs_commit, - fs_setattr: fsfilt_reiserfs_setattr, - fs_set_md: fsfilt_reiserfs_set_md, - fs_get_md: fsfilt_reiserfs_get_md, - fs_readpage: fsfilt_reiserfs_readpage, - fs_journal_data: fsfilt_reiserfs_journal_data, - fs_set_last_rcvd: fsfilt_reiserfs_set_last_rcvd, - fs_statfs: fsfilt_reiserfs_statfs, - fs_sync: fsfilt_reiserfs_sync, -}; - -static int __init fsfilt_reiserfs_init(void) -{ - return fsfilt_register_ops(&fsfilt_reiserfs_ops); -} - -static void __exit fsfilt_reiserfs_exit(void) -{ - fsfilt_unregister_ops(&fsfilt_reiserfs_ops); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre reiserfs Filesystem Helper v0.1"); -MODULE_LICENSE("GPL"); - -module_init(fsfilt_reiserfs_init); -module_exit(fsfilt_reiserfs_exit); diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c deleted file mode 100644 index 6fcf504..0000000 --- a/lustre/obdclass/genops.c +++ /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-2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * These are the only exported functions, they provide some generic - * infrastructure for managing object devices - */ - -#define DEBUG_SUBSYSTEM S_CLASS -#ifdef __KERNEL__ -#include /* for request_module() */ -#include -#include -#include -#include -#else -#include -#include -#include -#endif -#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); -void (*ptlrpc_abort_inflight_superhack)(struct obd_import *imp, - int dying_import); - -/* - * 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 *name) -{ - struct list_head *tmp; - struct obd_type *type; - CDEBUG(D_INFO, "SEARCH %s\n", name); - - 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(name) && - strcmp(type->typ_name, name) == 0) { - return type; - } - } - return NULL; -} - -struct obd_type *class_get_type(char *name) -{ - struct obd_type *type = class_search_type(name); - -#ifdef CONFIG_KMOD - if (!type) { - if (!request_module(name)) { - CDEBUG(D_INFO, "Loaded module '%s'\n", name); - type = class_search_type(name); - } else - CDEBUG(D_INFO, "Can't load module '%s'\n", name); - } -#endif - if (type) - __MOD_INC_USE_COUNT(type->typ_ops->o_owner); - return type; -} - -void class_put_type(struct obd_type *type) -{ - LASSERT(type); - __MOD_DEC_USE_COUNT(type->typ_ops->o_owner); -} - -int class_register_type(struct obd_ops *ops, struct lprocfs_vars *vars, - char *name) -{ - struct obd_type *type; - int rc = 0; - ENTRY; - - LASSERT(strnlen(name, 1024) < 1024); /* sanity check */ - - if (class_search_type(name)) { - CDEBUG(D_IOCTL, "Type %s already registered\n", name); - RETURN(-EEXIST); - } - - rc = -ENOMEM; - OBD_ALLOC(type, sizeof(*type)); - if (type == NULL) - RETURN(rc); - - OBD_ALLOC(type->typ_ops, sizeof(*type->typ_ops)); - OBD_ALLOC(type->typ_name, strlen(name) + 1); - if (type->typ_ops == NULL || type->typ_name == NULL) - GOTO (failed, rc); - - *(type->typ_ops) = *ops; - strcpy(type->typ_name, name); - list_add(&type->typ_chain, &obd_types); - - type->typ_procroot = lprocfs_register(type->typ_name, proc_lustre_root, - vars, type); - if (type->typ_procroot && IS_ERR(type->typ_procroot)) { - rc = PTR_ERR(type->typ_procroot); - type->typ_procroot = NULL; - list_del(&type->typ_chain); - GOTO (failed, rc); - } - - RETURN (0); - - failed: - if (type->typ_ops != NULL) - OBD_FREE(type->typ_name, strlen(name) + 1); - if (type->typ_ops != NULL) - OBD_FREE (type->typ_ops, sizeof (*type->typ_ops)); - RETURN(rc); -} - -int class_unregister_type(char *name) -{ - struct obd_type *type = class_search_type(name); - ENTRY; - - if (!type) { - CERROR("unknown obd type\n"); - RETURN(-EINVAL); - } - - if (type->typ_refcnt) { - CERROR("type %s has refcount (%d)\n", name, 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_remove(type->typ_procroot); - type->typ_procroot = NULL; - } - - list_del(&type->typ_chain); - OBD_FREE(type->typ_name, strlen(name) + 1); - if (type->typ_ops != NULL) - OBD_FREE(type->typ_ops, sizeof(*type->typ_ops)); - OBD_FREE(type, sizeof(*type)); - 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(struct obd_uuid *uuid) -{ - int res = -1; - int i; - - for (i = 0; i < MAX_OBD_DEVICES; i++) { - struct obd_device *obd = &obd_dev[i]; - if (strncmp(uuid->uuid, obd->obd_uuid.uuid, sizeof(obd->obd_uuid.uuid)) == 0) { - res = i; - return res; - } - } - - return res; -} - - -struct obd_device *class_uuid2obd(struct obd_uuid *uuid) -{ - int i; - - for (i = 0; i < MAX_OBD_DEVICES; i++) { - struct obd_device *obd = &obd_dev[i]; - if (strncmp(uuid->uuid, obd->obd_uuid.uuid, sizeof(obd->obd_uuid.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) -{ - LASSERT(exp->exp_cookie != DEAD_HANDLE_MAGIC); - - CDEBUG(D_IOCTL, "destroying export %p/%s\n", exp, - exp->exp_client_uuid.uuid); - - 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); - } - - /* Abort any inflight DLM requests and NULL out their (about to be - * freed) import. */ - if (exp->exp_ldlm_data.led_import.imp_obd) - ptlrpc_abort_inflight_superhack(&exp->exp_ldlm_data.led_import, - 1); - - exp->exp_cookie = DEAD_HANDLE_MAGIC; - kmem_cache_free(export_cachep, exp); -} - -/* a connection defines an export context in which preallocation can - be managed. */ -int class_connect(struct lustre_handle *exporth, struct obd_device *obd, - struct obd_uuid *cluuid) -{ - struct obd_export * export; - if (exporth == NULL) { - LBUG(); - return -EINVAL; - } - - if (obd == NULL) { - LBUG(); - return -EINVAL; - } - - if (cluuid == NULL) { - LBUG(); - return -EINVAL; - } - - export = class_new_export(obd); - if (!export) - return -ENOMEM; - - exporth->addr = (__u64) (unsigned long)export; - exporth->cookie = export->exp_cookie; - memcpy(&export->exp_client_uuid, cluuid, sizeof(export->exp_client_uuid)); - - CDEBUG(D_IOCTL, "connect: addr %Lx cookie %Lx\n", - (long long)exporth->addr, (long long)exporth->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 ? - (char *)export->exp_connection->c_remote_uuid.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 26bbdf7..0000000 --- a/lustre/obdclass/lprocfs_status.c +++ /dev/null @@ -1,341 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * Author: Hariharan Thantry - * - * 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_CLASS -#ifdef __KERNEL__ -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#endif - -#else -#include -#endif - -#include -#include - -#ifdef LPROCFS - -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; -} - -/* lprocfs API calls */ - -int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list, - void *data) -{ - if ((root == NULL) || (list == NULL)) - return -EINVAL; - - while (list->name) { - struct proc_dir_entry *cur_root, *proc; - char *pathcopy, *cur, *next; - int pathsize = strlen(list->name)+1; - - proc = NULL; - cur_root = root; - - /* need copy of path for strsep */ - OBD_ALLOC(pathcopy, pathsize); - if (!pathcopy) - return -ENOMEM; - - next = pathcopy; - strcpy(pathcopy, list->name); - - while (cur_root && (cur = strsep(&next, "/"))) { - if (*cur =='\0') /* skip double/trailing "/" */ - continue; - - proc = lprocfs_srch(cur_root, cur); - CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n", - cur_root->name, cur, next, - (proc ? "exists" : "new")); - if (next) - cur_root = (proc ? proc : - proc_mkdir(cur, cur_root)); - else if (!proc) - proc = create_proc_entry(cur, 0444, cur_root); - } - - OBD_FREE(pathcopy, pathsize); - - if ((cur_root==NULL) || (proc==NULL)) { - CERROR("LprocFS: No memory to create /proc entry %s", - list->name); - return -ENOMEM; - } - - proc->read_proc = list->read_fptr; - proc->write_proc = list->write_fptr; - proc->data = (list->data ? list->data : data); - list++; - } - return 0; -} - -void lprocfs_remove(struct proc_dir_entry* root) -{ - struct proc_dir_entry *temp = root; - struct proc_dir_entry *rm_entry; - struct proc_dir_entry *parent; - - LASSERT(root != NULL); - parent = root->parent; - LASSERT(parent != NULL); - - 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; - } -} - -struct proc_dir_entry *lprocfs_register(const char *name, - struct proc_dir_entry *parent, - struct lprocfs_vars *list, void *data) -{ - struct proc_dir_entry *newchild; - - newchild = lprocfs_srch(parent, name); - if (newchild) { - CERROR(" Lproc: Attempting to register %s more than once \n", - name); - return ERR_PTR(-EALREADY); - } - - newchild = proc_mkdir(name, parent); - if (newchild && list) { - int rc = lprocfs_add_vars(newchild, list, data); - if (rc) { - lprocfs_remove(newchild); - return ERR_PTR(rc); - } - } - return newchild; -} - -/* Generic callbacks */ - -int lprocfs_rd_u64(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - LASSERT(data != NULL); - *eof = 1; - return snprintf(page, count, LPU64"\n", *(__u64 *)data); -} - -int lprocfs_rd_uuid(char* page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device* dev = (struct obd_device*)data; - - LASSERT(dev != NULL); - *eof = 1; - return snprintf(page, count, "%s\n", dev->obd_uuid.uuid); -} - -int lprocfs_rd_name(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device* dev = (struct obd_device *)data; - - LASSERT(dev != NULL); - LASSERT(dev->obd_name != NULL); - *eof = 1; - return snprintf(page, count, "%s\n", dev->obd_name); -} - -int lprocfs_rd_blksize(char* page, char **start, off_t off, int count, - int *eof, struct statfs *sfs) -{ - LASSERT(sfs != NULL); - *eof = 1; - return snprintf(page, count, "%lu\n", sfs->f_bsize); -} - -int lprocfs_rd_kbytestotal(char* page, char **start, off_t off, int count, - int *eof, struct statfs *sfs) -{ - __u32 blk_size; - __u64 result; - - LASSERT(sfs != NULL); - blk_size = sfs->f_bsize >> 10; - result = sfs->f_blocks; - - while (blk_size >>= 1) - result <<= 1; - - *eof = 1; - return snprintf(page, count, LPU64"\n", result); -} - -int lprocfs_rd_kbytesfree(char* page, char **start, off_t off, int count, - int *eof, struct statfs *sfs) -{ - __u32 blk_size; - __u64 result; - - LASSERT(sfs != NULL); - blk_size = sfs->f_bsize >> 10; - result = sfs->f_bfree; - - while (blk_size >>= 1) - result <<= 1; - - *eof = 1; - return snprintf(page, count, LPU64"\n", result); -} - -int lprocfs_rd_filestotal(char* page, char **start, off_t off, int count, - int *eof, struct statfs *sfs) -{ - LASSERT(sfs != NULL); - *eof = 1; - return snprintf(page, count, "%ld\n", sfs->f_files); -} - -int lprocfs_rd_filesfree(char* page, char **start, off_t off, int count, - int *eof, struct statfs *sfs) -{ - LASSERT(sfs != NULL); - *eof = 1; - return snprintf(page, count, "%ld\n", sfs->f_ffree); -} - -int lprocfs_rd_filegroups(char* page, char **start, off_t off, int count, - int *eof, struct statfs *sfs) -{ - *eof = 1; - return snprintf(page, count, "unimplemented\n"); -} - -int lprocfs_rd_server_uuid(char* page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device* obd = (struct obd_device*)data; - struct client_obd* cli; - - LASSERT(obd != NULL); - cli = &obd->u.cli; - *eof = 1; - return snprintf(page, count, "%s\n", cli->cl_target_uuid.uuid); -} - -int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device*)data; - struct ptlrpc_connection *conn; - - LASSERT(obd != NULL); - conn = obd->u.cli.cl_import.imp_connection; - LASSERT(conn != NULL); - *eof = 1; - return snprintf(page, count, "%s\n", conn->c_remote_uuid.uuid); -} - -int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_type* class = (struct obd_type*) data; - - LASSERT(class != NULL); - *eof = 1; - return snprintf(page, count, "%d\n", class->typ_refcnt); -} - -int lprocfs_obd_attach(struct obd_device *dev, struct lprocfs_vars *list) -{ - int rc = 0; - - LASSERT(dev != NULL); - LASSERT(dev->obd_type != NULL); - LASSERT(dev->obd_type->typ_procroot != NULL); - - dev->obd_proc_entry = lprocfs_register(dev->obd_name, - dev->obd_type->typ_procroot, - list, dev); - if (IS_ERR(dev->obd_proc_entry)) { - rc = PTR_ERR(dev->obd_proc_entry); - dev->obd_proc_entry = NULL; - } - return rc; -} - -int lprocfs_obd_detach(struct obd_device *dev) -{ - if (dev && dev->obd_proc_entry) { - lprocfs_remove(dev->obd_proc_entry); - dev->obd_proc_entry = NULL; - } - return 0; -} - -#endif /* LPROCFS*/ - -EXPORT_SYMBOL(lprocfs_register); -EXPORT_SYMBOL(lprocfs_remove); -EXPORT_SYMBOL(lprocfs_add_vars); -EXPORT_SYMBOL(lprocfs_obd_attach); -EXPORT_SYMBOL(lprocfs_obd_detach); - -EXPORT_SYMBOL(lprocfs_rd_u64); -EXPORT_SYMBOL(lprocfs_rd_uuid); -EXPORT_SYMBOL(lprocfs_rd_name); -EXPORT_SYMBOL(lprocfs_rd_server_uuid); -EXPORT_SYMBOL(lprocfs_rd_conn_uuid); -EXPORT_SYMBOL(lprocfs_rd_numrefs); - -EXPORT_SYMBOL(lprocfs_rd_blksize); -EXPORT_SYMBOL(lprocfs_rd_kbytestotal); -EXPORT_SYMBOL(lprocfs_rd_kbytesfree); -EXPORT_SYMBOL(lprocfs_rd_filestotal); -EXPORT_SYMBOL(lprocfs_rd_filesfree); -EXPORT_SYMBOL(lprocfs_rd_filegroups); diff --git a/lustre/obdclass/lustre_handles.c b/lustre/obdclass/lustre_handles.c deleted file mode 100644 index 01dd75b..0000000 --- a/lustre/obdclass/lustre_handles.c +++ /dev/null @@ -1,166 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Phil Schwan - * - * This file is part of Portals, http://www.sf.net/projects/sandiaportals/ - * - * Portals is free software; you can redistribute it and/or - * modify it under the terms of version 2.1 of the GNU Lesser General - * Public License as published by the Free Software Foundation. - * - * Portals is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Portals; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define DEBUG_SUBSYSTEM S_PORTALS -#ifdef __KERNEL__ -#include -#include -#else -#include -#endif - - -#include -#include - -static spinlock_t handle_lock = SPIN_LOCK_UNLOCKED; -static spinlock_t random_lock = SPIN_LOCK_UNLOCKED; -static struct list_head *handle_hash = NULL; -static int handle_count = 0; - -#define HANDLE_HASH_SIZE (1 << 14) -#define HANDLE_HASH_MASK (HANDLE_HASH_SIZE - 1) - -void class_handle_hash(struct portals_handle *h, portals_handle_addref_cb cb) -{ - struct list_head *bucket; - ENTRY; - - LASSERT(h != NULL); - LASSERT(list_empty(&h->h_link)); - - /* My hypothesis is that get_random_bytes, if called from two threads at - * the same time, will return the same bytes. -phil */ - spin_lock(&random_lock); - get_random_bytes(&h->h_cookie, sizeof(h->h_cookie)); - spin_unlock(&random_lock); - - h->h_addref = cb; - - bucket = handle_hash + (h->h_cookie & HANDLE_HASH_MASK); - - CDEBUG(D_INFO, "adding object %p with handle "LPX64" to hash\n", - h, h->h_cookie); - - spin_lock(&handle_lock); - list_add(&h->h_link, bucket); - handle_count++; - spin_unlock(&handle_lock); - EXIT; -} - -static void class_handle_unhash_nolock(struct portals_handle *h) -{ - LASSERT(!list_empty(&h->h_link)); - - CDEBUG(D_INFO, "removing object %p with handle "LPX64" from hash\n", - h, h->h_cookie); - - handle_count--; - list_del_init(&h->h_link); -} - -void class_handle_unhash(struct portals_handle *h) -{ - spin_lock(&handle_lock); - class_handle_unhash_nolock(h); - spin_unlock(&handle_lock); -} - -void *class_handle2object(__u64 cookie) -{ - struct list_head *bucket, *tmp; - void *retval = NULL; - ENTRY; - - LASSERT(handle_hash != NULL); - - spin_lock(&handle_lock); - bucket = handle_hash + (cookie & HANDLE_HASH_MASK); - - list_for_each(tmp, bucket) { - struct portals_handle *h; - h = list_entry(tmp, struct portals_handle, h_link); - - if (h->h_cookie == cookie) { - h->h_addref(h); - retval = h; - break; - } - } - spin_unlock(&handle_lock); - - RETURN(retval); -} - -int class_handle_init(void) -{ - struct list_head *bucket; - - LASSERT(handle_hash == NULL); - - PORTAL_ALLOC(handle_hash, sizeof(*handle_hash) * HANDLE_HASH_SIZE); - if (handle_hash == NULL) - return -ENOMEM; - - for (bucket = handle_hash + HANDLE_HASH_SIZE - 1; bucket >= handle_hash; - bucket--) - INIT_LIST_HEAD(bucket); - - return 0; -} - -static void cleanup_all_handles(void) -{ - int i; - - spin_lock(&handle_lock); - for (i = 0; i < HANDLE_HASH_SIZE; i++) { - struct list_head *tmp, *pos; - list_for_each_safe(tmp, pos, &(handle_hash[i])) { - struct portals_handle *h; - h = list_entry(tmp, struct portals_handle, h_link); - - CERROR("forcing cleanup for handle "LPX64"\n", - h->h_cookie); - - class_handle_unhash_nolock(h); - } - } - spin_lock(&handle_lock); -} - -void class_handle_cleanup(void) -{ - LASSERT(handle_hash != NULL); - - if (handle_count != 0) { - CERROR("handle_count at cleanup: %d\n", handle_count); - cleanup_all_handles(); - } - - PORTAL_FREE(handle_hash, sizeof(*handle_hash) * HANDLE_HASH_SIZE); - handle_hash = NULL; - - if (handle_count) - CERROR("leaked %d handles\n", handle_count); -} diff --git a/lustre/obdclass/lustre_peer.c b/lustre/obdclass/lustre_peer.c deleted file mode 100644 index 016354c..0000000 --- a/lustre/obdclass/lustre_peer.c +++ /dev/null @@ -1,179 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#define DEBUG_SUBSYSTEM S_RPC - -#ifdef __KERNEL__ -# include -# include -# include -#else -# include -#endif -#include -#include -#include -#include -#include -#include -#include - -struct uuid_nid_data { - struct list_head head; - ptl_nid_t nid; - char *uuid; - __u32 nal; - ptl_handle_ni_t ni; -}; - -/* FIXME: This should probably become more elegant than a global linked list */ -static struct list_head g_uuid_list; -static spinlock_t g_uuid_lock; - -void class_init_uuidlist(void) -{ - INIT_LIST_HEAD(&g_uuid_list); - spin_lock_init(&g_uuid_lock); -} - -void class_exit_uuidlist(void) -{ - struct list_head *tmp, *n; - - /* Module going => sole user => don't need to lock g_uuid_list */ - list_for_each_safe(tmp, n, &g_uuid_list) { - struct uuid_nid_data *data = - list_entry(tmp, struct uuid_nid_data, head); - - PORTAL_FREE(data->uuid, strlen(data->uuid) + 1); - PORTAL_FREE(data, sizeof(*data)); - } -} - -int lustre_uuid_to_peer(char *uuid, struct lustre_peer *peer) -{ - struct list_head *tmp; - - spin_lock (&g_uuid_lock); - - list_for_each(tmp, &g_uuid_list) { - struct uuid_nid_data *data = - list_entry(tmp, struct uuid_nid_data, head); - - if (strcmp(data->uuid, uuid) == 0) { - peer->peer_nid = data->nid; - peer->peer_ni = data->ni; - - spin_unlock (&g_uuid_lock); - return 0; - } - } - - spin_unlock (&g_uuid_lock); - return -1; -} - -int class_add_uuid(char *uuid, __u64 nid, __u32 nal) -{ - const ptl_handle_ni_t *nip; - struct uuid_nid_data *data; - int rc; - int nob = strnlen (uuid, PAGE_SIZE) + 1; - - if (nob > PAGE_SIZE) - return -EINVAL; - - nip = kportal_get_ni (nal); - if (nip == NULL) { - CERROR("get_ni failed: is the NAL module loaded?\n"); - return -EIO; - } - - rc = -ENOMEM; - PORTAL_ALLOC(data, sizeof(*data)); - if (data == NULL) - goto fail_0; - - PORTAL_ALLOC(data->uuid, nob); - if (data == NULL) - goto fail_1; - - memcpy(data->uuid, uuid, nob); - data->nid = nid; - data->nal = nal; - data->ni = *nip; - - spin_lock (&g_uuid_lock); - - list_add(&data->head, &g_uuid_list); - - spin_unlock (&g_uuid_lock); - - return 0; - - fail_1: - PORTAL_FREE (data, sizeof (*data)); - fail_0: - kportal_put_ni (nal); - return (rc); -} - -/* delete only one entry if uuid is specified, otherwise delete all */ -int class_del_uuid (char *uuid) -{ - struct list_head deathrow; - struct list_head *tmp; - struct list_head *n; - struct uuid_nid_data *data; - - INIT_LIST_HEAD (&deathrow); - - spin_lock (&g_uuid_lock); - - list_for_each_safe(tmp, n, &g_uuid_list) { - data = list_entry(tmp, struct uuid_nid_data, head); - - if (uuid == NULL || strcmp(data->uuid, uuid) == 0) { - list_del (&data->head); - list_add (&data->head, &deathrow); - if (uuid) - break; - } - } - - spin_unlock (&g_uuid_lock); - - if (list_empty (&deathrow)) - return -EINVAL; - - do { - data = list_entry(deathrow.next, struct uuid_nid_data, head); - - list_del (&data->head); - - kportal_put_ni (data->nal); - PORTAL_FREE(data->uuid, strlen(data->uuid) + 1); - PORTAL_FREE(data, sizeof(*data)); - } while (!list_empty (&deathrow)); - - return 0; -} diff --git a/lustre/obdclass/statfs_pack.c b/lustre/obdclass/statfs_pack.c deleted file mode 100644 index 1998ba3..0000000 --- a/lustre/obdclass/statfs_pack.c +++ /dev/null @@ -1,115 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * 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. - * - * (Un)packing of OST/MDS requests - * - */ - -#define DEBUG_SUBSYSTEM S_CLASS - -#define EXPORT_SYMTAB -#ifndef __KERNEL__ -#include -#endif - -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#endif - -#include -#include -#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); -} - -void obd_statfs_unpack(struct obd_statfs *tgt, struct obd_statfs *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; -} - -int obd_self_statfs(struct obd_device *obd, struct statfs *sfs) -{ - struct lustre_handle conn; - struct obd_export *export, *my_export = NULL; - struct obd_statfs osfs = { 0 }; - int rc; - ENTRY; - - if (list_empty(&obd->obd_exports)) { - export = my_export = class_new_export(obd); - if (export == NULL) - RETURN(-ENOMEM); - } else - export = list_entry(obd->obd_exports.next, typeof(*export), - exp_obd_chain); - conn.addr = (unsigned long)export; - conn.cookie = export->exp_cookie; - - rc = obd_statfs(&conn, &osfs); - if (!rc) - statfs_unpack(sfs, &osfs); - - if (my_export) - class_destroy_export(my_export); - RETURN(rc); -} - -EXPORT_SYMBOL(obd_statfs_pack); -EXPORT_SYMBOL(obd_statfs_unpack); -EXPORT_SYMBOL(statfs_pack); -EXPORT_SYMBOL(statfs_unpack); -EXPORT_SYMBOL(obd_self_statfs); diff --git a/lustre/obdclass/sysctl.c b/lustre/obdclass/sysctl.c deleted file mode 100644 index 125f392..0000000 --- a/lustre/obdclass/sysctl.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) 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 -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#include -#endif -#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 */ -/* XXX temporary, as we play with sync osts.. */ -#define OBD_SYNCFILTER 8 - -#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 }, - {OBD_SYNCFILTER, "filter_sync_on_commit", &obd_sync_filter, sizeof(int), - 0644, NULL, &proc_dointvec}, - { 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 fed9a8f..0000000 --- a/lustre/obdclass/uuid.c +++ /dev/null @@ -1,140 +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% - */ -#define DEBUG_SUBSYSTEM S_CLASS - -#ifdef __KERNEL__ -#include -#include -#else -#include -#endif - -#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(struct obd_uuid 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, struct obd_uuid *out) -{ - struct uuid uuid; - - uuid_unpack(uu, &uuid); - sprintf(out->uuid, - "%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 f8ed503..0000000 --- a/lustre/obdecho/Makefile.am +++ /dev/null @@ -1,20 +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 LIBLUSTRE -lib_LIBRARIES = libobdecho.a -libobdecho_a_SOURCES = echo_client.c -else -MODULE = obdecho -modulefs_DATA = obdecho.o -EXTRA_PROGRAMS = obdecho -LINX= -obdecho_SOURCES = echo.c echo_client.c lproc_echo.c $(LINX) -endif - -include $(top_srcdir)/Rules - diff --git a/lustre/obdecho/echo.c b/lustre/obdecho/echo.c deleted file mode 100644 index 1796957..0000000 --- a/lustre/obdecho/echo.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-2003 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_ECHO - -#include -#include -#include -#include -#include -#include - -#define ECHO_INIT_OBJID 0x1000000000000000ULL -#define ECHO_HANDLE_MAGIC 0xabcd0123fedc9876ULL - -#define ECHO_OBJECT0_NPAGES 16 -static struct page *echo_object0_pages[ECHO_OBJECT0_NPAGES]; - -/* should be generic per-obd stats... */ -struct xprocfs_io_stat { - __u64 st_read_bytes; - __u64 st_read_reqs; - __u64 st_write_bytes; - __u64 st_write_reqs; - __u64 st_getattr_reqs; - __u64 st_setattr_reqs; - __u64 st_create_reqs; - __u64 st_destroy_reqs; - __u64 st_statfs_reqs; - __u64 st_sync_reqs; - __u64 st_open_reqs; - __u64 st_close_reqs; - __u64 st_punch_reqs; -}; - -static struct xprocfs_io_stat xprocfs_iostats[NR_CPUS]; -static struct proc_dir_entry *xprocfs_dir; - -#define XPROCFS_BUMP_MYCPU_IOSTAT(field, count) \ -do { \ - xprocfs_iostats[smp_processor_id()].field += (count); \ -} while (0) - -#define DECLARE_XPROCFS_SUM_STAT(field) \ -static long long \ -xprocfs_sum_##field (void) \ -{ \ - long long stat = 0; \ - int i; \ - \ - for (i = 0; i < smp_num_cpus; i++) \ - stat += xprocfs_iostats[i].field; \ - return (stat); \ -} -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -DECLARE_XPROCFS_SUM_STAT (st_read_bytes) -DECLARE_XPROCFS_SUM_STAT (st_read_reqs) -DECLARE_XPROCFS_SUM_STAT (st_write_bytes) -DECLARE_XPROCFS_SUM_STAT (st_write_reqs) -DECLARE_XPROCFS_SUM_STAT (st_getattr_reqs) -DECLARE_XPROCFS_SUM_STAT (st_setattr_reqs) -DECLARE_XPROCFS_SUM_STAT (st_create_reqs) -DECLARE_XPROCFS_SUM_STAT (st_destroy_reqs) -DECLARE_XPROCFS_SUM_STAT (st_statfs_reqs) -DECLARE_XPROCFS_SUM_STAT (st_sync_reqs) -DECLARE_XPROCFS_SUM_STAT (st_open_reqs) -DECLARE_XPROCFS_SUM_STAT (st_close_reqs) -DECLARE_XPROCFS_SUM_STAT (st_punch_reqs) -#endif - -static int -xprocfs_rd_stat (char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - long long (*fn)(void) = (long long(*)(void))data; - int len; - - *eof = 1; - if (off != 0) - return (0); - - len = snprintf (page, count, "%Ld\n", fn()); - *start = page; - return (len); -} - - -static void -xprocfs_add_stat(char *name, long long (*fn)(void)) -{ - struct proc_dir_entry *entry; - - entry = create_proc_entry (name, S_IFREG|S_IRUGO, xprocfs_dir); - if (entry == NULL) { - CERROR ("Can't add procfs stat %s\n", name); - return; - } - - entry->data = fn; - entry->read_proc = xprocfs_rd_stat; - entry->write_proc = NULL; -} - -static void -xprocfs_init (char *name) -{ - char dirname[64]; - - snprintf (dirname, sizeof (dirname), "sys/%s", name); - - xprocfs_dir = proc_mkdir (dirname, NULL); - if (xprocfs_dir == NULL) { - CERROR ("Can't make dir\n"); - return; - } - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - xprocfs_add_stat ("read_bytes", xprocfs_sum_st_read_bytes); - xprocfs_add_stat ("read_reqs", xprocfs_sum_st_read_reqs); - xprocfs_add_stat ("write_bytes", xprocfs_sum_st_write_bytes); - xprocfs_add_stat ("write_reqs", xprocfs_sum_st_write_reqs); - xprocfs_add_stat ("getattr_reqs", xprocfs_sum_st_getattr_reqs); - xprocfs_add_stat ("setattr_reqs", xprocfs_sum_st_setattr_reqs); - xprocfs_add_stat ("create_reqs", xprocfs_sum_st_create_reqs); - xprocfs_add_stat ("destroy_reqs", xprocfs_sum_st_destroy_reqs); - xprocfs_add_stat ("statfs_reqs", xprocfs_sum_st_statfs_reqs); - xprocfs_add_stat ("sync_reqs", xprocfs_sum_st_sync_reqs); - xprocfs_add_stat ("open_reqs", xprocfs_sum_st_open_reqs); - xprocfs_add_stat ("close_reqs", xprocfs_sum_st_close_reqs); - xprocfs_add_stat ("punch_reqs", xprocfs_sum_st_punch_reqs); -#endif -} - -void xprocfs_fini (void) -{ - if (xprocfs_dir == NULL) - return; - - remove_proc_entry ("read_bytes", xprocfs_dir); - remove_proc_entry ("read_reqs", xprocfs_dir); - remove_proc_entry ("write_bytes", xprocfs_dir); - remove_proc_entry ("write_reqs", xprocfs_dir); - remove_proc_entry ("getattr_reqs", xprocfs_dir); - remove_proc_entry ("setattr_reqs", xprocfs_dir); - remove_proc_entry ("create_reqs", xprocfs_dir); - remove_proc_entry ("destroy_reqs", xprocfs_dir); - remove_proc_entry ("statfs_reqs", xprocfs_dir); - remove_proc_entry ("sync_reqs", xprocfs_dir); - remove_proc_entry ("open_reqs", xprocfs_dir); - remove_proc_entry ("close_reqs", xprocfs_dir); - remove_proc_entry ("punch_reqs", xprocfs_dir); - - remove_proc_entry (xprocfs_dir->name, xprocfs_dir->parent); - xprocfs_dir = NULL; -} - -static int echo_connect(struct lustre_handle *conn, struct obd_device *obd, - struct obd_uuid *cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - return class_connect(conn, obd, cluuid); -} - -static int echo_disconnect(struct lustre_handle *conn) -{ - struct obd_export *exp = class_conn2export(conn); - - LASSERT (exp != NULL); - - ldlm_cancel_locks_for_export (exp); - return (class_disconnect (conn)); -} - -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_trans_info *oti) -{ - struct obd_device *obd = class_conn2obd(conn); - - XPROCFS_BUMP_MYCPU_IOSTAT (st_create_reqs, 1); - - if (!obd) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - if (!(oa->o_mode && S_IFMT)) { - CERROR("echo 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_trans_info *oti) -{ - struct obd_device *obd = class_conn2obd(conn); - - XPROCFS_BUMP_MYCPU_IOSTAT (st_destroy_reqs, 1); - - 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, struct obd_trans_info *oti) -{ - struct lustre_handle *fh = obdo_handle (oa); - struct obd_device *obd = class_conn2obd (conn); - - XPROCFS_BUMP_MYCPU_IOSTAT (st_open_reqs, 1); - - 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); - } - - fh->addr = oa->o_id; - fh->cookie = ECHO_HANDLE_MAGIC; - - oa->o_valid |= OBD_MD_FLHANDLE; - return 0; -} - -static int echo_close(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md, struct obd_trans_info *oti) -{ - struct lustre_handle *fh = obdo_handle (oa); - struct obd_device *obd = class_conn2obd(conn); - - XPROCFS_BUMP_MYCPU_IOSTAT (st_close_reqs, 1); - - if (!obd) { - CERROR("invalid client "LPX64"\n", conn->addr); - return (-EINVAL); - } - - if (!(oa->o_valid & OBD_MD_FLHANDLE)) { - CERROR("obdo missing FLHANDLE valid flag: %08x\n", oa->o_valid); - return (-EINVAL); - } - - if (fh->cookie != ECHO_HANDLE_MAGIC) { - CERROR ("invalid file handle on close: "LPX64"\n", fh->cookie); - return (-EINVAL); - } - - 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; - - XPROCFS_BUMP_MYCPU_IOSTAT (st_getattr_reqs, 1); - - 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); - } - - obdo_cpy_md(oa, &obd->u.echo.oa, oa->o_valid); - oa->o_id = id; - - return 0; -} - -static int echo_setattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md, struct obd_trans_info *oti) -{ - struct obd_device *obd = class_conn2obd(conn); - - XPROCFS_BUMP_MYCPU_IOSTAT (st_setattr_reqs, 1); - - 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_trans_info *oti) -{ - struct obd_device *obd; - struct niobuf_local *r = res; - int rc = 0; - int i; - ENTRY; - - if ((cmd & OBD_BRW_WRITE) != 0) - XPROCFS_BUMP_MYCPU_IOSTAT (st_write_reqs, 1); - else - XPROCFS_BUMP_MYCPU_IOSTAT (st_read_reqs, 1); - - 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 isobj0 = obj->ioo_id == 0; - int verify = !isobj0; - int j; - - for (j = 0 ; j < obj->ioo_bufcnt ; j++, nb++, r++) { - - if (isobj0 && - (nb->offset >> PAGE_SHIFT) < ECHO_OBJECT0_NPAGES) { - r->page = echo_object0_pages[nb->offset >> - PAGE_SHIFT]; - /* Take extra ref so __free_pages() can be called OK */ - get_page (r->page); - } else { - r->page = alloc_pages(gfp_mask, 0); - if (r->page == NULL) { - CERROR("can't get page %u/%u 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 (cmd == OBD_BRW_READ) { - XPROCFS_BUMP_MYCPU_IOSTAT(st_read_bytes,r->len); - if (verify) - page_debug_setup(r->addr, r->len, - r->offset,obj->ioo_id); - } else { - XPROCFS_BUMP_MYCPU_IOSTAT(st_write_bytes, - r->len); - 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); - /* NB if this is an 'object0' page, __free_pages will just - * lose the extra ref gained above */ - __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_trans_info *oti) -{ - struct obd_device *obd; - struct niobuf_local *r = res; - int rc = 0; - int vrc = 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); - } - - CDEBUG(D_PAGE, "$$$$ use page %p, addr %p@"LPU64"\n", - r->page, addr, r->offset); - - if (verify) { - vrc = page_debug_check("echo", addr, r->len, - r->offset, obj->ioo_id); - /* check all the pages always */ - if (vrc != 0 && rc == 0) - rc = vrc; - } - - kunmap(page); - /* NB see comment above regarding object0 pages */ - 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(rc); - -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); - /* NB see comment above regarding object0 pages */ - __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; - - spin_lock_init(&obddev->u.echo.eo_lock); - obddev->u.echo.eo_lastino = ECHO_INIT_OBJID; - - obddev->obd_namespace = - ldlm_namespace_new("echo-tgt", LDLM_NAMESPACE_SERVER); - if (obddev->obd_namespace == NULL) { - LBUG(); - RETURN(-ENOMEM); - } - - ptlrpc_init_client (LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL, - "echo_ldlm_cb_client", &obddev->obd_ldlm_client); - 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) -{ - struct lprocfs_static_vars lvars; - - lprocfs_init_vars(&lvars); - return lprocfs_obd_attach(dev, lvars.obd_vars); -} - -int echo_detach(struct obd_device *dev) -{ - return lprocfs_obd_detach(dev); -} - -static struct obd_ops echo_obd_ops = { - o_owner: THIS_MODULE, - 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 void -echo_object0_pages_fini (void) -{ - int i; - - for (i = 0; i < ECHO_OBJECT0_NPAGES; i++) - if (echo_object0_pages[i] != NULL) { - __free_pages (echo_object0_pages[i], 0); - echo_object0_pages[i] = NULL; - } -} - -static int -echo_object0_pages_init (void) -{ - struct page *pg; - int i; - - for (i = 0; i < ECHO_OBJECT0_NPAGES; i++) { - int gfp_mask = (i < ECHO_OBJECT0_NPAGES/2) ? - GFP_KERNEL : GFP_HIGHUSER; - - pg = alloc_pages (gfp_mask, 0); - if (pg == NULL) { - echo_object0_pages_fini (); - return (-ENOMEM); - } - - memset (kmap (pg), 0, PAGE_SIZE); - kunmap (pg); - - echo_object0_pages[i] = pg; - } - - return (0); -} - -static int __init obdecho_init(void) -{ - struct lprocfs_static_vars lvars; - int rc; - - printk(KERN_INFO "Lustre Echo OBD driver; info@clusterfs.com\n"); - - lprocfs_init_vars(&lvars); - - xprocfs_init ("echo"); - - rc = echo_object0_pages_init (); - if (rc != 0) - goto failed_0; - - rc = class_register_type(&echo_obd_ops, lvars.module_vars, - OBD_ECHO_DEVICENAME); - if (rc != 0) - goto failed_1; - - rc = echo_client_init(); - if (rc == 0) - RETURN (0); - - class_unregister_type(OBD_ECHO_DEVICENAME); - failed_1: - echo_object0_pages_fini (); - failed_0: - xprocfs_fini (); - - RETURN(rc); -} - -static void __exit obdecho_exit(void) -{ - echo_client_cleanup(); - class_unregister_type(OBD_ECHO_DEVICENAME); - echo_object0_pages_fini (); - xprocfs_fini (); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Testing Echo OBD driver"); -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 9f7544b..0000000 --- a/lustre/obdecho/echo_client.c +++ /dev/null @@ -1,1166 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2001-2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define DEBUG_SUBSYSTEM S_ECHO -#ifdef __KERNEL__ -#include -#include -#include -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#include -#endif -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include -#include /* for LL_IOC_LOV_SETSTRIPE */ - -#if 0 -static void -echo_printk_object (char *msg, struct ec_object *eco) -{ - struct lov_stripe_md *lsm = eco->eco_lsm; - int i; - - printk (KERN_INFO "%s: object %p: "LPX64", refs %d%s: "LPX64 - "=%u!%u@%d\n", msg, eco, eco->eco_id, eco->eco_refcount, - eco->eco_deleted ? "(deleted) " : "", - lsm->lsm_object_id, lsm->lsm_stripe_size, - lsm->lsm_stripe_count, lsm->lsm_stripe_offset); - - for (i = 0; i < lsm->lsm_stripe_count; i++) - printk (KERN_INFO " [%2u]"LPX64"\n", - lsm->lsm_oinfo[i].loi_ost_idx, - lsm->lsm_oinfo[i].loi_id); -} -#endif - -static struct ec_object * -echo_find_object_locked (struct obd_device *obd, obd_id id) -{ - struct echo_client_obd *ec = &obd->u.echo_client; - struct ec_object *eco = NULL; - struct list_head *el; - - list_for_each (el, &ec->ec_objects) { - eco = list_entry (el, struct ec_object, eco_obj_chain); - - if (eco->eco_id == id) - return (eco); - } - return (NULL); -} - -static int -echo_copyout_lsm (struct lov_stripe_md *lsm, void *ulsm, int ulsm_nob) -{ - int nob; - - nob = offsetof (struct lov_stripe_md, lsm_oinfo[lsm->lsm_stripe_count]); - if (nob > ulsm_nob) - return (-EINVAL); - - if (copy_to_user (ulsm, lsm, nob)) - return (-EFAULT); - - return (0); -} - -static int -echo_copyin_lsm (struct obd_device *obd, struct lov_stripe_md *lsm, - void *ulsm, int ulsm_nob) -{ - struct echo_client_obd *ec = &obd->u.echo_client; - int nob; - - if (ulsm_nob < sizeof (*lsm)) - return (-EINVAL); - - if (copy_from_user (lsm, ulsm, sizeof (*lsm))) - return (-EFAULT); - - nob = lsm->lsm_stripe_count * sizeof (lsm->lsm_oinfo[0]); - - if (ulsm_nob < nob || - lsm->lsm_stripe_count > ec->ec_nstripes || - lsm->lsm_magic != LOV_MAGIC || - (lsm->lsm_stripe_offset != 0 && - lsm->lsm_stripe_offset != 0xffffffff && - lsm->lsm_stripe_offset >= ec->ec_nstripes) || - (lsm->lsm_stripe_size & (PAGE_SIZE - 1)) != 0 || - ((__u64)lsm->lsm_stripe_size * lsm->lsm_stripe_count > ~0UL)) - return (-EINVAL); - - LASSERT (ec->ec_lsmsize >= sizeof (*lsm) + nob); - - if (copy_from_user(lsm->lsm_oinfo, - ((struct lov_stripe_md *)ulsm)->lsm_oinfo, nob)) - return (-EFAULT); - - return (0); -} - -static struct ec_object * -echo_allocate_object (struct obd_device *obd) -{ - struct echo_client_obd *ec = &obd->u.echo_client; - struct ec_object *eco; - - OBD_ALLOC (eco, sizeof (*eco)); - if (eco == NULL) - return (NULL); - - OBD_ALLOC (eco->eco_lsm, ec->ec_lsmsize); - if (eco->eco_lsm == NULL) { - OBD_FREE (eco, sizeof (*eco)); - return (NULL); - } - - eco->eco_device = obd; - eco->eco_deleted = 0; - eco->eco_refcount = 0; - eco->eco_lsm->lsm_magic = LOV_MAGIC; - /* leave stripe count 0 by default */ - - return (eco); -} - -static void -echo_free_object (struct ec_object *eco) -{ - struct obd_device *obd = eco->eco_device; - struct echo_client_obd *ec = &obd->u.echo_client; - - LASSERT (eco->eco_refcount == 0); - OBD_FREE (eco->eco_lsm, ec->ec_lsmsize); - OBD_FREE (eco, sizeof (*eco)); -} - -static int -echo_create_object (struct obd_device *obd, int on_target, struct obdo *oa, - void *ulsm, int ulsm_nob) -{ - struct echo_client_obd *ec = &obd->u.echo_client; - struct ec_object *eco2; - struct ec_object *eco; - struct lov_stripe_md *lsm; - int rc; - int i; - - if ((oa->o_valid & OBD_MD_FLID) == 0 && /* no obj id */ - (on_target || /* set_stripe */ - ec->ec_nstripes != 0)) { /* LOV */ - CERROR ("No valid oid\n"); - return (-EINVAL); - } - - eco = echo_allocate_object (obd); - if (eco == NULL) - return (-ENOMEM); - - lsm = eco->eco_lsm; - - if (ulsm != NULL) { - rc = echo_copyin_lsm (obd, lsm, ulsm, ulsm_nob); - if (rc != 0) - goto failed; - } - - /* setup object ID here for !on_target and LOV hint */ - if ((oa->o_valid & OBD_MD_FLID) != 0) - eco->eco_id = lsm->lsm_object_id = oa->o_id; - - /* defaults -> actual values */ - if (lsm->lsm_stripe_offset == 0xffffffff) - lsm->lsm_stripe_offset = 0; - - if (lsm->lsm_stripe_count == 0) - lsm->lsm_stripe_count = ec->ec_nstripes; - - if (lsm->lsm_stripe_size == 0) - lsm->lsm_stripe_size = PAGE_SIZE; - - /* setup stripes: indices + default ids if required */ - for (i = 0; i < lsm->lsm_stripe_count; i++) { - if (lsm->lsm_oinfo[i].loi_id == 0) - lsm->lsm_oinfo[i].loi_id = lsm->lsm_object_id; - - lsm->lsm_oinfo[i].loi_ost_idx = - (lsm->lsm_stripe_offset + i) % ec->ec_nstripes; - } - - if (on_target) { - rc = obd_create (&ec->ec_conn, oa, &lsm, NULL); - if (rc != 0) - goto failed; - - /* See what object ID we were given */ - LASSERT ((oa->o_valid & OBD_MD_FLID) != 0); - eco->eco_id = lsm->lsm_object_id = oa->o_id; - } - - spin_lock (&ec->ec_lock); - - eco2 = echo_find_object_locked (obd, oa->o_id); - if (eco2 != NULL) { /* conflict */ - spin_unlock (&ec->ec_lock); - - CERROR ("Can't create object id "LPX64": id already exists%s\n", - oa->o_id, on_target ? " (undoing create)" : ""); - - if (on_target) - obd_destroy (&ec->ec_conn, oa, lsm, NULL); - - rc = -EEXIST; - goto failed; - } - - list_add (&eco->eco_obj_chain, &ec->ec_objects); - spin_unlock (&ec->ec_lock); - CDEBUG (D_INFO, - "created %p: "LPX64"=%u#%u&%d refs %d del %d\n", - eco, eco->eco_id, - eco->eco_lsm->lsm_stripe_size, - eco->eco_lsm->lsm_stripe_count, - eco->eco_lsm->lsm_stripe_offset, - eco->eco_refcount, eco->eco_deleted); - return (0); - - failed: - echo_free_object (eco); - return (rc); -} - -static int -echo_get_object (struct ec_object **ecop, struct obd_device *obd, - struct obdo *oa) -{ - struct echo_client_obd *ec = &obd->u.echo_client; - struct ec_object *eco; - struct ec_object *eco2; - int rc; - - if ((oa->o_valid & OBD_MD_FLID) == 0) - { - CERROR ("No valid oid\n"); - return (-EINVAL); - } - - spin_lock (&ec->ec_lock); - eco = echo_find_object_locked (obd, oa->o_id); - if (eco != NULL) { - if (eco->eco_deleted) /* being deleted */ - return (-EAGAIN); /* (see comment in cleanup) */ - - eco->eco_refcount++; - spin_unlock (&ec->ec_lock); - *ecop = eco; - CDEBUG (D_INFO, - "found %p: "LPX64"=%u#%u&%d refs %d del %d\n", - eco, eco->eco_id, - eco->eco_lsm->lsm_stripe_size, - eco->eco_lsm->lsm_stripe_count, - eco->eco_lsm->lsm_stripe_offset, - eco->eco_refcount, eco->eco_deleted); - return (0); - } - spin_unlock (&ec->ec_lock); - - if (ec->ec_nstripes != 0) /* striping required */ - return (-ENOENT); - - eco = echo_allocate_object (obd); - if (eco == NULL) - return (-ENOMEM); - - eco->eco_id = eco->eco_lsm->lsm_object_id = oa->o_id; - - spin_lock (&ec->ec_lock); - - eco2 = echo_find_object_locked (obd, oa->o_id); - if (eco2 == NULL) { /* didn't race */ - list_add (&eco->eco_obj_chain, &ec->ec_objects); - spin_unlock (&ec->ec_lock); - eco->eco_refcount = 1; - *ecop = eco; - CDEBUG (D_INFO, - "created %p: "LPX64"=%u#%u&%d refs %d del %d\n", - eco, eco->eco_id, - eco->eco_lsm->lsm_stripe_size, - eco->eco_lsm->lsm_stripe_count, - eco->eco_lsm->lsm_stripe_offset, - eco->eco_refcount, eco->eco_deleted); - return (0); - } - - if (eco2->eco_deleted) - rc = -EAGAIN; /* lose race */ - else { - eco2->eco_refcount++; /* take existing */ - *ecop = eco2; - rc = 0; - LASSERT (eco2->eco_id == eco2->eco_lsm->lsm_object_id); - CDEBUG (D_INFO, - "found(2) %p: "LPX64"=%u#%u&%d refs %d del %d\n", - eco2, eco2->eco_id, - eco2->eco_lsm->lsm_stripe_size, - eco2->eco_lsm->lsm_stripe_count, - eco2->eco_lsm->lsm_stripe_offset, - eco2->eco_refcount, eco2->eco_deleted); - } - - spin_unlock (&ec->ec_lock); - - echo_free_object (eco); - return (rc); -} - -static void -echo_put_object (struct ec_object *eco) -{ - struct obd_device *obd = eco->eco_device; - struct echo_client_obd *ec = &obd->u.echo_client; - - /* Release caller's ref on the object. - * delete => mark for deletion when last ref goes - */ - - spin_lock (&ec->ec_lock); - - eco->eco_refcount--; - LASSERT (eco->eco_refcount >= 0); - - if (eco->eco_refcount != 0 || - !eco->eco_deleted) { - spin_unlock (&ec->ec_lock); - return; - } - - spin_unlock (&ec->ec_lock); - - /* NB leave obj in the object list. We must prevent anyone from - * attempting to enqueue on this object number until we can be - * sure there will be no more lock callbacks. - */ - obd_cancel_unused (&ec->ec_conn, eco->eco_lsm, 0); - - /* now we can let it go */ - spin_lock (&ec->ec_lock); - list_del (&eco->eco_obj_chain); - spin_unlock (&ec->ec_lock); - - LASSERT (eco->eco_refcount == 0); - - echo_free_object (eco); -} - -static void -echo_get_stripe_off_id (struct lov_stripe_md *lsm, obd_off *offp, obd_id *idp) -{ - unsigned long stripe_count; - unsigned long stripe_size; - unsigned long width; - unsigned long woffset; - int stripe_index; - obd_off offset; - - if (lsm->lsm_stripe_count <= 1) - return; - - offset = *offp; - stripe_size = lsm->lsm_stripe_size; - stripe_count = lsm->lsm_stripe_count; - - /* width = # bytes in all stripes */ - width = stripe_size * stripe_count; - - /* woffset = offset within a width; offset = whole number of widths */ - woffset = do_div (offset, width); - - stripe_index = woffset / stripe_size; - - *idp = lsm->lsm_oinfo[stripe_index].loi_id; - *offp = offset * stripe_size + woffset % stripe_size; -} - -static int -echo_client_kbrw (struct obd_device *obd, int rw, - struct obdo *oa, struct lov_stripe_md *lsm, - obd_off offset, obd_size count) -{ - struct echo_client_obd *ec = &obd->u.echo_client; - struct obd_brw_set *set; - obd_count npages; - struct brw_page *pga; - struct brw_page *pgp; - obd_off off; - int i; - int rc; - int verify; - int gfp_mask; - - /* oa_id == 0 => speed test (no verification) else... - * oa & 1 => use HIGHMEM - */ - verify = (oa->o_id != 0); - gfp_mask = ((oa->o_id & 1) == 0) ? GFP_KERNEL : GFP_HIGHUSER; - - LASSERT(rw == OBD_BRW_WRITE || rw == OBD_BRW_READ); - - if (count <= 0 || - (count & (PAGE_SIZE - 1)) != 0 || - (lsm != NULL && - lsm->lsm_object_id != oa->o_id)) - return (-EINVAL); - - set = obd_brw_set_new(); - if (set == NULL) - return (-ENOMEM); - - /* XXX think again with misaligned I/O */ - npages = count >> PAGE_SHIFT; - - rc = -ENOMEM; - OBD_ALLOC(pga, npages * sizeof(*pga)); - if (pga == NULL) - goto out_0; - - for (i = 0, pgp = pga, off = offset; - i < npages; - i++, pgp++, off += PAGE_SIZE) { - - LASSERT (pgp->pg == NULL); /* for cleanup */ - - rc = -ENOMEM; - pgp->pg = alloc_pages (gfp_mask, 0); - if (pgp->pg == NULL) - goto out_1; - - pgp->count = PAGE_SIZE; - pgp->off = off; - pgp->flag = 0; - - if (verify) { - void *addr = kmap(pgp->pg); - obd_off stripe_off = off; - obd_id stripe_id = oa->o_id; - - if (rw == OBD_BRW_WRITE) { - echo_get_stripe_off_id(lsm, &stripe_off, - &stripe_id); - page_debug_setup(addr, pgp->count, - stripe_off, stripe_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->ec_conn, lsm, npages, pga, set, NULL); - if (rc == 0) - rc = ll_brw_sync_wait(set, CB_PHASE_START); - - out_1: - if (rc != 0) - verify = 0; - - for (i = 0, pgp = pga; i < npages; i++, pgp++) { - if (pgp->pg == NULL) - continue; - - if (verify) { - void *addr = kmap(pgp->pg); - obd_off stripe_off = pgp->off; - obd_id stripe_id = oa->o_id; - int vrc; - - echo_get_stripe_off_id (lsm, &stripe_off, &stripe_id); - vrc = page_debug_check("test_brw", addr, pgp->count, - stripe_off, stripe_id); - if (vrc != 0 && rc == 0) - rc = vrc; - - kunmap(pgp->pg); - } - __free_pages(pgp->pg, 0); - } - OBD_FREE(pga, npages * sizeof(*pga)); - out_0: - obd_brw_set_free(set); - return (rc); -} - -#ifdef __KERNEL__ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -static int echo_client_ubrw(struct obd_device *obd, int rw, - struct obdo *oa, struct lov_stripe_md *lsm, - obd_off offset, obd_size count, char *buffer) -{ - struct echo_client_obd *ec = &obd->u.echo_client; - struct obd_brw_set *set; - obd_count npages; - struct brw_page *pga; - struct brw_page *pgp; - obd_off off; - struct kiobuf *kiobuf; - int i; - int rc; - - LASSERT (rw == OBD_BRW_WRITE || - rw == OBD_BRW_READ); - - /* NB: for now, only whole pages, page aligned */ - - if (count <= 0 || - ((long)buffer & (PAGE_SIZE - 1)) != 0 || - (count & (PAGE_SIZE - 1)) != 0 || - (lsm != NULL && lsm->lsm_object_id != oa->o_id)) - return (-EINVAL); - - set = obd_brw_set_new(); - if (set == NULL) - return (-ENOMEM); - - /* XXX think again with misaligned I/O */ - npages = count >> PAGE_SHIFT; - - rc = -ENOMEM; - OBD_ALLOC(pga, npages * sizeof(*pga)); - if (pga == NULL) - goto out_0; - - rc = alloc_kiovec (1, &kiobuf); - if (rc != 0) - goto out_1; - - rc = map_user_kiobuf ((rw == OBD_BRW_READ) ? READ : WRITE, - kiobuf, (unsigned long)buffer, count); - if (rc != 0) - goto out_2; - - LASSERT (kiobuf->offset == 0); - LASSERT (kiobuf->nr_pages == npages); - - for (i = 0, off = offset, pgp = pga; - i < npages; - i++, off += PAGE_SIZE, pgp++) { - pgp->off = off; - pgp->pg = kiobuf->maplist[i]; - pgp->count = PAGE_SIZE; - pgp->flag = 0; - } - - set->brw_callback = ll_brw_sync_wait; - rc = obd_brw(rw, &ec->ec_conn, lsm, npages, pga, set, NULL); - - if (rc == 0) - rc = ll_brw_sync_wait(set, CB_PHASE_START); - - // if (rw == OBD_BRW_READ) - // mark_dirty_kiobuf (kiobuf, count); - - unmap_kiobuf (kiobuf); - out_2: - free_kiovec (1, &kiobuf); - out_1: - OBD_FREE(pga, npages * sizeof(*pga)); - out_0: - obd_brw_set_free(set); - return (rc); -} -#else -static int echo_client_ubrw(struct obd_device *obd, int rw, - struct obdo *oa, struct lov_stripe_md *lsm, - obd_off offset, obd_size count, char *buffer) -{ - LBUG(); - return 0; -} -#endif -#endif - -static int -echo_open (struct obd_export *exp, struct obdo *oa) -{ - struct obd_device *obd = exp->exp_obd; - struct echo_client_obd *ec = &obd->u.echo_client; - struct lustre_handle *ufh = obdo_handle (oa); - struct ec_open_object *ecoo; - struct ec_object *eco; - int rc; - - rc = echo_get_object (&eco, obd, oa); - if (rc != 0) - return (rc); - - rc = -ENOMEM; - OBD_ALLOC (ecoo, sizeof (*ecoo)); - if (ecoo == NULL) - goto failed_0; - - rc = obd_open (&ec->ec_conn, oa, eco->eco_lsm, NULL); - if (rc != 0) - goto failed_1; - - memcpy (&ecoo->ecoo_oa, oa, sizeof (*oa)); - ecoo->ecoo_object = eco; - /* ecoo takes ref from echo_get_object() above */ - - spin_lock (&ec->ec_lock); - - list_add (&ecoo->ecoo_exp_chain, &exp->exp_ec_data.eced_open_head); - - ufh->addr = (__u64)((long) ecoo); - ufh->cookie = ecoo->ecoo_cookie = ec->ec_unique++; - - spin_unlock (&ec->ec_lock); - return (0); - - failed_1: - OBD_FREE (ecoo, sizeof (*ecoo)); - failed_0: - echo_put_object (eco); - return (rc); -} - -static int -echo_close (struct obd_export *exp, struct obdo *oa) -{ - struct obd_device *obd = exp->exp_obd; - struct echo_client_obd *ec = &obd->u.echo_client; - struct lustre_handle *ufh = obdo_handle (oa); - struct ec_open_object *ecoo = NULL; - int found = 0; - struct list_head *el; - int rc; - - if ((oa->o_valid & OBD_MD_FLHANDLE) == 0) - return (-EINVAL); - - spin_lock (&ec->ec_lock); - - list_for_each (el, &exp->exp_ec_data.eced_open_head) { - ecoo = list_entry (el, struct ec_open_object, ecoo_exp_chain); - if ((__u64)((long)ecoo) == ufh->addr) { - found = (ecoo->ecoo_cookie == ufh->cookie); - if (found) - list_del (&ecoo->ecoo_exp_chain); - break; - } - } - - spin_unlock (&ec->ec_lock); - - if (!found) - return (-EINVAL); - - rc = obd_close (&ec->ec_conn, &ecoo->ecoo_oa, - ecoo->ecoo_object->eco_lsm, NULL); - - echo_put_object (ecoo->ecoo_object); - OBD_FREE (ecoo, sizeof (*ecoo)); - - return (rc); -} - -static int -echo_ldlm_callback (struct ldlm_lock *lock, struct ldlm_lock_desc *new, - void *data, int flag) -{ - struct ec_object *eco = (struct ec_object *)data; - struct echo_client_obd *ec = &(eco->eco_device->u.echo_client); - struct lustre_handle lockh; - struct list_head *el; - int found = 0; - int rc; - - ldlm_lock2handle (lock, &lockh); - - /* #ifdef this out if we're not feeling paranoid */ - spin_lock (&ec->ec_lock); - list_for_each (el, &ec->ec_objects) { - found = (eco == list_entry(el, struct ec_object, - eco_obj_chain)); - if (found) - break; - } - spin_unlock (&ec->ec_lock); - LASSERT (found); - - switch (flag) { - case LDLM_CB_BLOCKING: - CDEBUG (D_INFO, "blocking callback on "LPX64", handle "LPX64"." - LPX64"\n", eco->eco_id, lockh.addr, lockh.cookie); - rc = ldlm_cli_cancel (&lockh); - if (rc != ELDLM_OK) - CERROR ("ldlm_cli_cancel failed: %d\n", rc); - break; - - case LDLM_CB_CANCELING: - CDEBUG (D_INFO, "canceling callback on "LPX64", handle "LPX64"." - LPX64"\n", eco->eco_id, lockh.addr, lockh.cookie); - break; - - default: - LBUG (); - } - - return (0); -} - -static int -echo_enqueue (struct obd_export *exp, struct obdo *oa, - int mode, obd_off offset, obd_size nob) -{ - struct obd_device *obd = exp->exp_obd; - struct echo_client_obd *ec = &obd->u.echo_client; - struct lustre_handle *ulh = obdo_handle (oa); - struct ec_object *eco; - struct ec_lock *ecl; - int flags; - int rc; - - if (!(mode == LCK_PR || mode == LCK_PW)) - return (-EINVAL); - - if ((offset & (PAGE_SIZE - 1)) != 0 || - (nob & (PAGE_SIZE - 1)) != 0) - return (-EINVAL); - - rc = echo_get_object (&eco, obd, oa); - if (rc != 0) - return (rc); - - rc = -ENOMEM; - OBD_ALLOC (ecl, sizeof (*ecl)); - if (ecl == NULL) - goto failed_0; - - ecl->ecl_mode = mode; - ecl->ecl_object = eco; - ecl->ecl_extent.start = offset; - ecl->ecl_extent.end = (nob == 0) ? ((obd_off)-1) : (offset + nob - 1); - - flags = 0; - rc = obd_enqueue (&ec->ec_conn, eco->eco_lsm, NULL, LDLM_EXTENT, - &ecl->ecl_extent,sizeof(ecl->ecl_extent), mode, - &flags, echo_ldlm_callback, eco, sizeof (*eco), - &ecl->ecl_handle); - if (rc != 0) - goto failed_1; - - CDEBUG (D_INFO, "enqueue handle "LPX64"."LPX64"\n", - ecl->ecl_handle.addr, ecl->ecl_handle.cookie); - - /* NB ecl takes object ref from echo_get_object() above */ - - spin_lock (&ec->ec_lock); - - list_add (&ecl->ecl_exp_chain, &exp->exp_ec_data.eced_locks); - - ulh->addr = (__u64)((long)ecl); - ulh->cookie = ecl->ecl_cookie = ec->ec_unique++; - - spin_unlock (&ec->ec_lock); - - oa->o_valid |= OBD_MD_FLHANDLE; - return (0); - - failed_1: - OBD_FREE (ecl, sizeof (*ecl)); - failed_0: - echo_put_object (eco); - return (rc); -} - -static int -echo_cancel (struct obd_export *exp, struct obdo *oa) -{ - struct obd_device *obd = exp->exp_obd; - struct echo_client_obd *ec = &obd->u.echo_client; - struct lustre_handle *ulh = obdo_handle (oa); - struct ec_lock *ecl = NULL; - int found = 0; - struct list_head *el; - int rc; - - if ((oa->o_valid & OBD_MD_FLHANDLE) == 0) - return (-EINVAL); - - spin_lock (&ec->ec_lock); - - list_for_each (el, &exp->exp_ec_data.eced_locks) { - ecl = list_entry (el, struct ec_lock, ecl_exp_chain); - - if ((__u64)((long)ecl) == ulh->addr) { - found = (ecl->ecl_cookie == ulh->cookie); - if (found) - list_del (&ecl->ecl_exp_chain); - break; - } - } - - spin_unlock (&ec->ec_lock); - - if (!found) - return (-ENOENT); - - rc = obd_cancel (&ec->ec_conn, - ecl->ecl_object->eco_lsm, - ecl->ecl_mode, - &ecl->ecl_handle); - - echo_put_object (ecl->ecl_object); - OBD_FREE (ecl, sizeof (*ecl)); - - return (rc); -} - -static int echo_iocontrol(unsigned int cmd, struct lustre_handle *obdconn, - int len, void *karg, void *uarg) -{ - struct obd_export *exp = class_conn2export (obdconn); - struct obd_device *obd; - struct echo_client_obd *ec; - struct ec_object *eco; - struct obd_ioctl_data *data = karg; - int rw = OBD_BRW_READ; - int rc = 0; - ENTRY; - - if (exp == NULL) { - CERROR("ioctl: No device\n"); - GOTO(out, rc = -EINVAL); - } - - obd = exp->exp_obd; - ec = &obd->u.echo_client; - - switch (cmd) { - case OBD_IOC_CREATE: /* may create echo object */ - if (!capable (CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); - - rc = echo_create_object (obd, 1, &data->ioc_obdo1, - data->ioc_pbuf1, data->ioc_plen1); - GOTO(out, rc); - - case OBD_IOC_DESTROY: - if (!capable (CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); - - rc = echo_get_object (&eco, obd, &data->ioc_obdo1); - if (rc == 0) { - rc = obd_destroy(&ec->ec_conn, &data->ioc_obdo1, - eco->eco_lsm, NULL); - if (rc == 0) - eco->eco_deleted = 1; - echo_put_object(eco); - } - GOTO(out, rc); - - case OBD_IOC_GETATTR: - rc = echo_get_object (&eco, obd, &data->ioc_obdo1); - if (rc == 0) { - rc = obd_getattr(&ec->ec_conn, &data->ioc_obdo1, - eco->eco_lsm); - echo_put_object(eco); - } - GOTO(out, rc); - - case OBD_IOC_SETATTR: - if (!capable (CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); - - rc = echo_get_object (&eco, obd, &data->ioc_obdo1); - if (rc == 0) { - rc = obd_setattr(&ec->ec_conn, &data->ioc_obdo1, - eco->eco_lsm, NULL); - echo_put_object(eco); - } - GOTO(out, rc); - - case OBD_IOC_OPEN: - rc = echo_open (exp, &data->ioc_obdo1); - GOTO(out, rc); - - case OBD_IOC_CLOSE: - rc = echo_close (exp, &data->ioc_obdo1); - GOTO(out, rc); - - case OBD_IOC_BRW_WRITE: - if (!capable (CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); - - rw = OBD_BRW_WRITE; - /* fall through */ - case OBD_IOC_BRW_READ: - rc = echo_get_object (&eco, obd, &data->ioc_obdo1); - if (rc == 0) { - if (data->ioc_pbuf2 == NULL) // NULL user data pointer - rc = echo_client_kbrw(obd, rw, &data->ioc_obdo1, - eco->eco_lsm, - data->ioc_offset, - data->ioc_count); - else -#ifdef __KERNEL__ - rc = echo_client_ubrw(obd, rw, &data->ioc_obdo1, - eco->eco_lsm, - data->ioc_offset, - data->ioc_count, - data->ioc_pbuf2); -#endif - echo_put_object(eco); - } - GOTO(out, rc); - - case ECHO_IOC_GET_STRIPE: - rc = echo_get_object(&eco, obd, &data->ioc_obdo1); - if (rc == 0) { - rc = echo_copyout_lsm(eco->eco_lsm, data->ioc_pbuf1, - data->ioc_plen1); - echo_put_object(eco); - } - GOTO(out, rc); - - case ECHO_IOC_SET_STRIPE: - if (!capable (CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); - - if (data->ioc_pbuf1 == NULL) { /* unset */ - rc = echo_get_object(&eco, obd, &data->ioc_obdo1); - if (rc == 0) { - eco->eco_deleted = 1; - echo_put_object(eco); - } - } else { - rc = echo_create_object(obd, 0, &data->ioc_obdo1, - data->ioc_pbuf1, - data->ioc_plen1); - } - GOTO (out, rc); - - case ECHO_IOC_ENQUEUE: - if (!capable (CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); - - rc = echo_enqueue (exp, &data->ioc_obdo1, - data->ioc_conn1, /* lock mode */ - data->ioc_offset, data->ioc_count);/*extent*/ - GOTO (out, rc); - - case ECHO_IOC_CANCEL: - rc = echo_cancel (exp, &data->ioc_obdo1); - GOTO (out, rc); - - default: - CERROR ("echo_ioctl(): unrecognised ioctl %#x\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; - struct obd_uuid uuid; - struct lov_stripe_md *lsm = NULL; - struct obd_uuid echo_uuid = { "ECHO_UUID" }; - 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); - } - - obd_str2uuid(&uuid, data->ioc_inlbuf1); - tgt = class_uuid2obd(&uuid); - 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); - RETURN(rc = -EINVAL); - } - - spin_lock_init (&ec->ec_lock); - INIT_LIST_HEAD (&ec->ec_objects); - ec->ec_unique = 0; - - rc = obd_connect(&ec->ec_conn, tgt, &echo_uuid, NULL, NULL); - if (rc) { - CERROR("fail to connect to device %d\n", data->ioc_dev); - return (rc); - } - - ec->ec_lsmsize = obd_alloc_memmd (&ec->ec_conn, &lsm); - if (ec->ec_lsmsize < 0) { - CERROR ("Can't get # stripes: %d\n", rc); - obd_disconnect (&ec->ec_conn); - rc = ec->ec_lsmsize; - } else { - ec->ec_nstripes = lsm->lsm_stripe_count; - obd_free_memmd (&ec->ec_conn, &lsm); - } - - RETURN(rc); -} - -static int echo_cleanup(struct obd_device * obddev) -{ - struct list_head *el; - struct ec_object *eco; - 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); - } - - /* XXX assuming sole access */ - while (!list_empty (&ec->ec_objects)) { - el = ec->ec_objects.next; - eco = list_entry (el, struct ec_object, eco_obj_chain); - - LASSERT (eco->eco_refcount == 0); - eco->eco_refcount = 1; - eco->eco_deleted = 1; - echo_put_object (eco); - } - - rc = obd_disconnect (&ec->ec_conn); - if (rc != 0) - CERROR("fail to disconnect device: %d\n", rc); - - RETURN (rc); -} - -static int echo_connect(struct lustre_handle *conn, struct obd_device *src, - struct obd_uuid *cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct obd_export *exp; - int rc; - - rc = class_connect(conn, src, cluuid); - if (rc == 0) { - exp = class_conn2export (conn); - INIT_LIST_HEAD (&exp->exp_ec_data.eced_open_head); - INIT_LIST_HEAD (&exp->exp_ec_data.eced_locks); - } - - RETURN (rc); -} - -static int echo_disconnect(struct lustre_handle *conn) -{ - struct obd_export *exp = class_conn2export (conn); - struct obd_device *obd; - struct echo_client_obd *ec; - struct ec_open_object *ecoo; - struct ec_lock *ecl; - int rc; - - if (exp == NULL) - return (-EINVAL); - - obd = exp->exp_obd; - ec = &obd->u.echo_client; - - /* no more contention on export's lock list */ - while (!list_empty (&exp->exp_ec_data.eced_locks)) { - ecl = list_entry (exp->exp_ec_data.eced_locks.next, - struct ec_lock, ecl_exp_chain); - list_del (&ecl->ecl_exp_chain); - - rc = obd_cancel (&ec->ec_conn, ecl->ecl_object->eco_lsm, - ecl->ecl_mode, &ecl->ecl_handle); - - CERROR ("Cancel lock on object "LPX64" on disconnect (%d)\n", - ecl->ecl_object->eco_id, rc); - - echo_put_object (ecl->ecl_object); - OBD_FREE (ecl, sizeof (*ecl)); - } - - /* no more contention on export's open handle list */ - while (!list_empty (&exp->exp_ec_data.eced_open_head)) { - ecoo = list_entry (exp->exp_ec_data.eced_open_head.next, - struct ec_open_object, ecoo_exp_chain); - list_del (&ecoo->ecoo_exp_chain); - - rc = obd_close (&ec->ec_conn, &ecoo->ecoo_oa, - ecoo->ecoo_object->eco_lsm, NULL); - - CDEBUG (D_INFO, "Closed object "LPX64" on disconnect (%d)\n", - ecoo->ecoo_oa.o_id, rc); - - echo_put_object (ecoo->ecoo_object); - OBD_FREE (ecoo, sizeof (*ecoo)); - } - - rc = class_disconnect (conn); - RETURN (rc); -} - -static struct obd_ops echo_obd_ops = { - o_owner: THIS_MODULE, - o_setup: echo_setup, - o_cleanup: echo_cleanup, - o_iocontrol: echo_iocontrol, - o_connect: echo_connect, - o_disconnect: echo_disconnect -}; - -int echo_client_init(void) -{ - struct lprocfs_static_vars lvars; - - lprocfs_init_vars(&lvars); - return class_register_type(&echo_obd_ops, lvars.module_vars, - 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 6a16001..0000000 --- a/lustre/obdecho/lproc_echo.c +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_ECHO - -#include -#include - -#ifndef LPROCFS -struct lprocfs_vars lprocfs_obd_vars[] = { {0} }; -struct lprocfs_vars lprocfs_module_vars[] = { {0} }; -#else - -int rd_fstype(char* page, char **start, off_t off, int count, int *eof, - void *data) -{ - struct obd_device* dev = (struct obd_device*)data; - - LASSERT(dev != NULL); - *eof = 1; - return snprintf(page, count, "%s\n", dev->u.echo.eo_fstype); -} - -struct lprocfs_vars lprocfs_obd_vars[] = { - { "uuid", lprocfs_rd_uuid, 0, 0 }, - { "fstype", rd_fstype, 0, 0 }, - { 0 } -}; - -struct lprocfs_vars lprocfs_module_vars[] = { - { "num_refs", lprocfs_rd_numrefs, 0, 0 }, - { 0 } -}; - -#endif /* LPROCFS */ -LPROCFS_INIT_VARS(lprocfs_module_vars, lprocfs_obd_vars) 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 7e17804..0000000 --- a/lustre/obdfilter/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 = $(ENABLE_OST_RECOVERY) -MODULE = obdfilter -modulefs_DATA = obdfilter.o -EXTRA_PROGRAMS = obdfilter - -LINX=simple.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 8486c22..0000000 --- a/lustre/obdfilter/filter.c +++ /dev/null @@ -1,2700 +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-2003 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. - */ - -/* - * Invariant: Get O/R i_sem for lookup, if needed, before any journal ops - * (which need to get journal_lock, may block if journal full). - * - * Invariant: Call filter_start_transno() before any journal ops to avoid the - * same deadlock problem. We can (and want) to get rid of the - * transno sem in favour of the dir/inode i_sem to avoid single - * threaded operation on the OST. - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_FILTER - -#include -#include -#include // XXX kill me soon -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -#include -#endif - -static kmem_cache_t *filter_open_cache; -static kmem_cache_t *filter_dentry_cache; - -/* should be generic per-obd stats... */ -struct xprocfs_io_stat { - __u64 st_read_bytes; - __u64 st_read_reqs; - __u64 st_write_bytes; - __u64 st_write_reqs; - __u64 st_getattr_reqs; - __u64 st_setattr_reqs; - __u64 st_create_reqs; - __u64 st_destroy_reqs; - __u64 st_statfs_reqs; - __u64 st_syncfs_reqs; - __u64 st_open_reqs; - __u64 st_close_reqs; - __u64 st_punch_reqs; -}; - -static struct xprocfs_io_stat xprocfs_iostats[NR_CPUS]; -static struct proc_dir_entry *xprocfs_dir; - -#define XPROCFS_BUMP_MYCPU_IOSTAT(field, count) \ -do { \ - xprocfs_iostats[smp_processor_id()].field += (count); \ -} while (0) - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#define DECLARE_XPROCFS_SUM_STAT(field) \ -static long long \ -xprocfs_sum_##field (void) \ -{ \ - long long stat = 0; \ - int i; \ - \ - for (i = 0; i < smp_num_cpus; i++) \ - stat += xprocfs_iostats[i].field; \ - return (stat); \ -} - -DECLARE_XPROCFS_SUM_STAT (st_read_bytes) -DECLARE_XPROCFS_SUM_STAT (st_read_reqs) -DECLARE_XPROCFS_SUM_STAT (st_write_bytes) -DECLARE_XPROCFS_SUM_STAT (st_write_reqs) -DECLARE_XPROCFS_SUM_STAT (st_getattr_reqs) -DECLARE_XPROCFS_SUM_STAT (st_setattr_reqs) -DECLARE_XPROCFS_SUM_STAT (st_create_reqs) -DECLARE_XPROCFS_SUM_STAT (st_destroy_reqs) -DECLARE_XPROCFS_SUM_STAT (st_statfs_reqs) -DECLARE_XPROCFS_SUM_STAT (st_syncfs_reqs) -DECLARE_XPROCFS_SUM_STAT (st_open_reqs) -DECLARE_XPROCFS_SUM_STAT (st_close_reqs) -DECLARE_XPROCFS_SUM_STAT (st_punch_reqs) -#endif - -static int -xprocfs_rd_stat (char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - long long (*fn)(void) = (long long(*)(void))data; - int len; - - *eof = 1; - if (off != 0) - return (0); - - len = snprintf (page, count, "%Ld\n", fn()); - *start = page; - return (len); -} - - -static void -xprocfs_add_stat(char *name, long long (*fn)(void)) -{ - struct proc_dir_entry *entry; - - entry = create_proc_entry (name, S_IFREG|S_IRUGO, xprocfs_dir); - if (entry == NULL) { - CERROR ("Can't add procfs stat %s\n", name); - return; - } - - entry->data = fn; - entry->read_proc = xprocfs_rd_stat; - entry->write_proc = NULL; -} - -static void -xprocfs_init (char *name) -{ - char dirname[64]; - - snprintf (dirname, sizeof (dirname), "sys/%s", name); - - xprocfs_dir = proc_mkdir ("sys/obdfilter", NULL); - if (xprocfs_dir == NULL) { - CERROR ("Can't make dir\n"); - return; - } - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - xprocfs_add_stat ("read_bytes", xprocfs_sum_st_read_bytes); - xprocfs_add_stat ("read_reqs", xprocfs_sum_st_read_reqs); - xprocfs_add_stat ("write_bytes", xprocfs_sum_st_write_bytes); - xprocfs_add_stat ("write_reqs", xprocfs_sum_st_write_reqs); - xprocfs_add_stat ("getattr_reqs", xprocfs_sum_st_getattr_reqs); - xprocfs_add_stat ("setattr_reqs", xprocfs_sum_st_setattr_reqs); - xprocfs_add_stat ("create_reqs", xprocfs_sum_st_create_reqs); - xprocfs_add_stat ("destroy_reqs", xprocfs_sum_st_destroy_reqs); - xprocfs_add_stat ("statfs_reqs", xprocfs_sum_st_statfs_reqs); - xprocfs_add_stat ("syncfs_reqs", xprocfs_sum_st_syncfs_reqs); - xprocfs_add_stat ("open_reqs", xprocfs_sum_st_open_reqs); - xprocfs_add_stat ("close_reqs", xprocfs_sum_st_close_reqs); - xprocfs_add_stat ("punch_reqs", xprocfs_sum_st_punch_reqs); -#endif -} - -void xprocfs_fini (void) -{ - if (xprocfs_dir == NULL) - return; - - remove_proc_entry ("read_bytes", xprocfs_dir); - remove_proc_entry ("read_reqs", xprocfs_dir); - remove_proc_entry ("write_bytes", xprocfs_dir); - remove_proc_entry ("write_reqs", xprocfs_dir); - remove_proc_entry ("getattr_reqs", xprocfs_dir); - remove_proc_entry ("setattr_reqs", xprocfs_dir); - remove_proc_entry ("create_reqs", xprocfs_dir); - remove_proc_entry ("destroy_reqs", xprocfs_dir); - remove_proc_entry ("statfs_reqs", xprocfs_dir); - remove_proc_entry ("syncfs_reqs", xprocfs_dir); - remove_proc_entry ("open_reqs", xprocfs_dir); - remove_proc_entry ("close_reqs", xprocfs_dir); - remove_proc_entry ("punch_reqs", xprocfs_dir); - - remove_proc_entry (xprocfs_dir->name, xprocfs_dir->parent); - xprocfs_dir = NULL; -} - -#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]; -} - -static void filter_last_rcvd_cb(struct obd_device *obd, __u64 last_rcvd, - int error) -{ - CDEBUG(D_HA, "got callback for last_rcvd "LPD64": rc = %d\n", - last_rcvd, error); - if (!error && last_rcvd > obd->obd_last_committed) - obd->obd_last_committed = last_rcvd; -} - -void filter_start_transno(struct obd_export *export) -{ -#ifdef FILTER_TRANSNO_SEM - struct obd_device * obd = export->exp_obd; - ENTRY; - - down(&obd->u.filter.fo_transno_sem); -#endif -} - -/* Assumes caller has already pushed us into the kernel context. */ -int filter_finish_transno(struct obd_export *export, void *handle, - struct obd_trans_info *oti, int rc) -{ - __u64 last_rcvd; - struct obd_device *obd = export->exp_obd; - struct filter_obd *filter = &obd->u.filter; - struct filter_export_data *fed = &export->exp_filter_data; - struct filter_client_data *fcd = fed->fed_fcd; - loff_t off; - ssize_t written; - - /* Propagate error code. */ - if (rc) { -#ifdef FILTER_TRANSNO_SEM - up(&filter->fo_transno_sem); -#endif - RETURN(rc); - } - - if (!(obd->obd_flags & OBD_REPLAYABLE)) { - RETURN(0); - } - - /* we don't allocate new transnos for replayed requests */ -#if 0 - /* perhaps if transno already set? or should level be in oti? */ - if (req->rq_level == LUSTRE_CONN_RECOVD) - GOTO(out, rc = 0); -#endif - - off = fed->fed_lr_off; - -#ifndef FILTER_TRANSNO_SEM - spin_lock(&filter->fo_translock); -#endif - last_rcvd = le64_to_cpu(filter->fo_fsd->fsd_last_rcvd); - filter->fo_fsd->fsd_last_rcvd = cpu_to_le64(last_rcvd + 1); -#ifndef FILTER_TRANSNO_SEM - spin_unlock(&filter->fo_translock); -#endif - if (oti) - oti->oti_transno = last_rcvd; - fcd->fcd_last_rcvd = cpu_to_le64(last_rcvd); - fcd->fcd_mount_count = filter->fo_fsd->fsd_mount_count; - - /* get this from oti */ -#if 0 - if (oti) - fcd->fcd_last_xid = cpu_to_le64(oti->oti_xid); - else -#else - fcd->fcd_last_xid = 0; -#endif - fsfilt_set_last_rcvd(obd, last_rcvd, handle, filter_last_rcvd_cb); - written = lustre_fwrite(filter->fo_rcvd_filp, (char *)fcd, sizeof(*fcd), - &off); - CDEBUG(D_INODE, "wrote trans #"LPD64" for client %s at #%d: written = " - LPSZ"\n", last_rcvd, fcd->fcd_uuid, fed->fed_lr_idx, written); - -#ifdef FILTER_TRANSNO_SEM - up(&filter->fo_transno_sem); -#endif - if (written == sizeof(*fcd)) - RETURN(0); - CERROR("error writing to last_rcvd file: rc = %d\n", written); - if (written >= 0) - RETURN(-EIO); - - RETURN(written); -} - -/* write the pathname into the string */ -static char *filter_id(char *buf, struct filter_obd *filter, obd_id id, - obd_mode mode) -{ - if ((mode & S_IFMT) != S_IFREG || filter->fo_subdir_count == 0) - sprintf(buf, "O/%s/"LPU64, obd_mode_to_type(mode), id); - else - sprintf(buf, "O/%s/d%d/"LPU64, obd_mode_to_type(mode), - (int)id & (filter->fo_subdir_count - 1), id); - - return buf; -} - -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, -}; - -#define LAST_RCVD "last_rcvd" -#define INIT_OBJID 2 - -/* This limit is arbitrary, but for now we fit it in 1 page (32k clients) */ -#define FILTER_LR_MAX_CLIENTS (PAGE_SIZE * 8) -#define FILTER_LR_MAX_CLIENT_WORDS (FILTER_LR_MAX_CLIENTS/sizeof(unsigned long)) - -/* Add client data to the FILTER. We use a bitmap to locate a free space - * in the last_rcvd file if cl_idx 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 filter_client_add(struct filter_obd *filter, - struct filter_export_data *fed, int cl_idx) -{ - int new_client = (cl_idx == -1); - - LASSERT(filter->fo_last_rcvd_slots != NULL); - - /* the bitmap operations can handle cl_idx > sizeof(long) * 8, so - * there's no need for extra complication here - */ - if (new_client) { - cl_idx = find_first_zero_bit(filter->fo_last_rcvd_slots, - FILTER_LR_MAX_CLIENTS); - repeat: - if (cl_idx >= FILTER_LR_MAX_CLIENTS) { - CERROR("no client slots - fix FILTER_LR_MAX_CLIENTS\n"); - return -ENOMEM; - } - if (test_and_set_bit(cl_idx, filter->fo_last_rcvd_slots)) { - CERROR("FILTER client %d: found bit is set in bitmap\n", - cl_idx); - cl_idx = find_next_zero_bit(filter->fo_last_rcvd_slots, - FILTER_LR_MAX_CLIENTS, - cl_idx); - goto repeat; - } - } else { - if (test_and_set_bit(cl_idx, filter->fo_last_rcvd_slots)) { - CERROR("FILTER client %d: bit already set in bitmap!\n", - cl_idx); - LBUG(); - } - } - - fed->fed_lr_idx = cl_idx; - fed->fed_lr_off = le32_to_cpu(filter->fo_fsd->fsd_client_start) + - cl_idx * le16_to_cpu(filter->fo_fsd->fsd_client_size); - - CDEBUG(D_INFO, "client at index %d (%llu) with UUID '%s' added\n", - fed->fed_lr_idx, fed->fed_lr_off, fed->fed_fcd->fcd_uuid); - - if (new_client) { - struct obd_run_ctxt saved; - loff_t off = fed->fed_lr_off; - ssize_t written; - - CDEBUG(D_INFO, "writing client fcd at idx %u (%llu) (len %u)\n", - fed->fed_lr_idx,off,(unsigned int)sizeof(*fed->fed_fcd)); - - push_ctxt(&saved, &filter->fo_ctxt, NULL); - written = lustre_fwrite(filter->fo_rcvd_filp, - (char *)fed->fed_fcd, - sizeof(*fed->fed_fcd), &off); - pop_ctxt(&saved, &filter->fo_ctxt, NULL); - - if (written != sizeof(*fed->fed_fcd)) { - if (written < 0) - RETURN(written); - RETURN(-EIO); - } - } - return 0; -} - -int filter_client_free(struct obd_export *exp) -{ - struct filter_export_data *fed = &exp->exp_filter_data; - struct filter_obd *filter = &exp->exp_obd->u.filter; - struct filter_client_data zero_fcd; - struct obd_run_ctxt saved; - int written; - loff_t off; - - if (!fed->fed_fcd) - RETURN(0); - - LASSERT(filter->fo_last_rcvd_slots != NULL); - - off = fed->fed_lr_off; - - CDEBUG(D_INFO, "freeing client at idx %u (%lld) with UUID '%s'\n", - fed->fed_lr_idx, fed->fed_lr_off, fed->fed_fcd->fcd_uuid); - - if (!test_and_clear_bit(fed->fed_lr_idx, filter->fo_last_rcvd_slots)) { - CERROR("FILTER client %u: bit already clear in bitmap!!\n", - fed->fed_lr_idx); - LBUG(); - } - - memset(&zero_fcd, 0, sizeof zero_fcd); - push_ctxt(&saved, &filter->fo_ctxt, NULL); - written = lustre_fwrite(filter->fo_rcvd_filp, (const char *)&zero_fcd, - sizeof(zero_fcd), &off); - - /* XXX: this write gets lost sometimes, unless this sync is here. */ - file_fsync(filter->fo_rcvd_filp, filter->fo_rcvd_filp->f_dentry, 1); - pop_ctxt(&saved, &filter->fo_ctxt, NULL); - - if (written != sizeof(zero_fcd)) { - CERROR("error zeroing out client %s idx %u (%llu) in %s: %d\n", - fed->fed_fcd->fcd_uuid, fed->fed_lr_idx, fed->fed_lr_off, - LAST_RCVD, written); - } else { - CDEBUG(D_INFO, - "zeroed disconnecting client %s at idx %u (%llu)\n", - fed->fed_fcd->fcd_uuid, fed->fed_lr_idx,fed->fed_lr_off); - } - - OBD_FREE(fed->fed_fcd, sizeof(*fed->fed_fcd)); - - return 0; -} - -static int filter_free_server_data(struct filter_obd *filter) -{ - OBD_FREE(filter->fo_fsd, sizeof(*filter->fo_fsd)); - filter->fo_fsd = NULL; - OBD_FREE(filter->fo_last_rcvd_slots, - FILTER_LR_MAX_CLIENT_WORDS * sizeof(unsigned long)); - filter->fo_last_rcvd_slots = NULL; - return 0; -} - - -/* assumes caller is already in kernel ctxt */ -static int filter_update_server_data(struct file *filp, - struct filter_server_data *fsd) -{ - loff_t off = 0; - int rc; - - CDEBUG(D_INODE, "server uuid : %s\n", fsd->fsd_uuid); - CDEBUG(D_INODE, "server last_objid: "LPU64"\n", - le64_to_cpu(fsd->fsd_last_objid)); - CDEBUG(D_INODE, "server last_rcvd : "LPU64"\n", - le64_to_cpu(fsd->fsd_last_rcvd)); - CDEBUG(D_INODE, "server last_mount: "LPU64"\n", - le64_to_cpu(fsd->fsd_mount_count)); - - rc = lustre_fwrite(filp, (char *)fsd, sizeof(*fsd), &off); - if (rc != sizeof(*fsd)) { - CDEBUG(D_INODE, "error writing filter_server_data: rc = %d\n", - rc); - RETURN(-EIO); - } - RETURN(0); -} - -/* assumes caller has already in kernel ctxt */ -static int filter_init_server_data(struct obd_device *obd, struct file * filp, - __u64 init_lastobjid) -{ - struct filter_obd *filter = &obd->u.filter; - struct filter_server_data *fsd; - struct filter_client_data *fcd = NULL; - struct inode *inode = filp->f_dentry->d_inode; - unsigned long last_rcvd_size = inode->i_size; - __u64 mount_count; - int cl_idx; - loff_t off = 0; - int rc; - - /* ensure padding in the struct is the correct size */ - LASSERT (offsetof(struct filter_server_data, fsd_padding) + - sizeof(fsd->fsd_padding) == FILTER_LR_SERVER_SIZE); - LASSERT (offsetof(struct filter_client_data, fcd_padding) + - sizeof(fcd->fcd_padding) == FILTER_LR_CLIENT_SIZE); - - OBD_ALLOC(fsd, sizeof(*fsd)); - if (!fsd) - RETURN(-ENOMEM); - filter->fo_fsd = fsd; - - OBD_ALLOC(filter->fo_last_rcvd_slots, - FILTER_LR_MAX_CLIENT_WORDS * sizeof(unsigned long)); - if (filter->fo_last_rcvd_slots == NULL) { - OBD_FREE(fsd, sizeof(*fsd)); - RETURN(-ENOMEM); - } - - if (last_rcvd_size == 0) { - CERROR("%s: initializing new last_rcvd\n", obd->obd_name); - - memcpy(fsd->fsd_uuid, obd->obd_uuid.uuid,sizeof(fsd->fsd_uuid)); - fsd->fsd_last_objid = cpu_to_le64(init_lastobjid); - fsd->fsd_last_rcvd = 0; - mount_count = fsd->fsd_mount_count = 0; - fsd->fsd_server_size = cpu_to_le32(FILTER_LR_SERVER_SIZE); - fsd->fsd_client_start = cpu_to_le32(FILTER_LR_CLIENT_START); - fsd->fsd_client_size = cpu_to_le16(FILTER_LR_CLIENT_SIZE); - fsd->fsd_subdir_count = cpu_to_le16(FILTER_SUBDIR_COUNT); - filter->fo_subdir_count = FILTER_SUBDIR_COUNT; - } else { - ssize_t retval = lustre_fread(filp, (char *)fsd, sizeof(*fsd), - &off); - if (retval != sizeof(*fsd)) { - CDEBUG(D_INODE,"OBD filter: error reading lastobjid\n"); - GOTO(out, rc = -EIO); - } - mount_count = le64_to_cpu(fsd->fsd_mount_count); - filter->fo_subdir_count = le16_to_cpu(fsd->fsd_subdir_count); - } - - if (fsd->fsd_feature_incompat) { - CERROR("unsupported feature %x\n", - le32_to_cpu(fsd->fsd_feature_incompat)); - RETURN(-EINVAL); - } - if (fsd->fsd_feature_rocompat) { - CERROR("read-only feature %x\n", - le32_to_cpu(fsd->fsd_feature_rocompat)); - /* Do something like remount filesystem read-only */ - RETURN(-EINVAL); - } - - CDEBUG(D_INODE, "%s: server last_objid: "LPU64"\n", - obd->obd_name, le64_to_cpu(fsd->fsd_last_objid)); - CDEBUG(D_INODE, "%s: server last_rcvd : "LPU64"\n", - obd->obd_name, le64_to_cpu(fsd->fsd_last_rcvd)); - CDEBUG(D_INODE, "%s: server last_mount: "LPU64"\n", - obd->obd_name, mount_count); - CDEBUG(D_INODE, "%s: server data size: %u\n", - obd->obd_name, le32_to_cpu(fsd->fsd_server_size)); - CDEBUG(D_INODE, "%s: per-client data start: %u\n", - obd->obd_name, le32_to_cpu(fsd->fsd_client_start)); - CDEBUG(D_INODE, "%s: per-client data size: %u\n", - obd->obd_name, le32_to_cpu(fsd->fsd_client_size)); - CDEBUG(D_INODE, "%s: server subdir_count: %u\n", - obd->obd_name, le16_to_cpu(fsd->fsd_subdir_count)); - - /* - * When we do a clean FILTER 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. - */ - if (obd->obd_flags & OBD_REPLAYABLE) { - for (cl_idx = 0; off < last_rcvd_size; cl_idx++) { - __u64 last_rcvd; - int mount_age; - - if (!fcd) { - OBD_ALLOC(fcd, sizeof(*fcd)); - if (!fcd) - GOTO(err_fsd, rc = -ENOMEM); - } - - /* Don't assume off is incremented properly, in case - * sizeof(fsd) isn't the same as fsd->fsd_client_size. - */ - off = le32_to_cpu(fsd->fsd_client_start) + - cl_idx * le16_to_cpu(fsd->fsd_client_size); - rc = lustre_fread(filp, (char *)fcd, sizeof(*fcd), &off); - if (rc != sizeof(*fcd)) { - CERROR("error reading FILTER %s offset %d: rc = %d\n", - LAST_RCVD, cl_idx, rc); - if (rc > 0) /* XXX fatal error or just abort reading? */ - rc = -EIO; - break; - } - - if (fcd->fcd_uuid[0] == '\0') { - CDEBUG(D_INFO, "skipping zeroed client at offset %d\n", - cl_idx); - continue; - } - - last_rcvd = le64_to_cpu(fcd->fcd_last_rcvd); - - /* These exports are cleaned up by filter_disconnect(), so they - * need to be set up like real exports as filter_connect() does. - */ - mount_age = mount_count - le64_to_cpu(fcd->fcd_mount_count); - if (mount_age < FILTER_MOUNT_RECOV) { - struct obd_export *exp = class_new_export(obd); - struct filter_export_data *fed; - CERROR("RCVRNG CLIENT uuid: %s idx: %d lr: "LPU64 - " srv lr: "LPU64" mnt: "LPU64" last mount: " - LPU64"\n", fcd->fcd_uuid, cl_idx, - last_rcvd, le64_to_cpu(fsd->fsd_last_rcvd), - le64_to_cpu(fcd->fcd_mount_count), mount_count); - /* disabled until OST recovery is actually working */ - - if (!exp) { - rc = -ENOMEM; - break; - } - memcpy(&exp->exp_client_uuid.uuid, fcd->fcd_uuid, - sizeof exp->exp_client_uuid.uuid); - fed = &exp->exp_filter_data; - fed->fed_fcd = fcd; - filter_client_add(filter, fed, cl_idx); - /* create helper if export init gets more complex */ - INIT_LIST_HEAD(&fed->fed_open_head); - spin_lock_init(&fed->fed_lock); - - fcd = NULL; - obd->obd_recoverable_clients++; - } else { - CDEBUG(D_INFO, - "discarded client %d UUID '%s' count "LPU64"\n", - cl_idx, fcd->fcd_uuid, - le64_to_cpu(fcd->fcd_mount_count)); - } - - CDEBUG(D_OTHER, "client at idx %d has last_rcvd = "LPU64"\n", - cl_idx, last_rcvd); - - if (last_rcvd > le64_to_cpu(filter->fo_fsd->fsd_last_rcvd)) - filter->fo_fsd->fsd_last_rcvd = cpu_to_le64(last_rcvd); - } - - obd->obd_last_committed = le64_to_cpu(filter->fo_fsd->fsd_last_rcvd); - if (obd->obd_recoverable_clients) { - CERROR("RECOVERY: %d recoverable clients, last_rcvd "LPU64"\n", - obd->obd_recoverable_clients, - le64_to_cpu(filter->fo_fsd->fsd_last_rcvd)); - obd->obd_next_recovery_transno = obd->obd_last_committed + 1; - obd->obd_flags |= OBD_RECOVERING; - } - - if (fcd) - OBD_FREE(fcd, sizeof(*fcd)); - - } else { - CERROR("%s: recovery support OFF\n", obd->obd_name); - } - - fsd->fsd_mount_count = cpu_to_le64(mount_count + 1); - - /* save it,so mount count and last_recvd is current */ - rc = filter_update_server_data(filp, filter->fo_fsd); - -out: - RETURN(rc); - -err_fsd: - filter_free_server_data(filter); - RETURN(rc); -} - -/* 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, *O_dentry; - struct file *file; - struct inode *inode; - int i; - int rc = 0; - 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; - - /* - * Create directories and/or get dentries for each object type. - * This saves us from having to do multiple lookups for each one. - */ - O_dentry = filter->fo_dentry_O; - for (mode = 0; mode < (S_IFMT >> S_SHIFT); mode++) { - char *name = obd_type_by_mode[mode]; - - if (!name) { - filter->fo_dentry_O_mode[mode] = NULL; - continue; - } - dentry = simple_mkdir(O_dentry, name, 0700); - CDEBUG(D_INODE, "got/created O/%s: %p\n", name, dentry); - if (IS_ERR(dentry)) { - rc = PTR_ERR(dentry); - CERROR("cannot create O/%s: rc = %d\n", name, rc); - GOTO(err_O_mode, rc); - } - filter->fo_dentry_O_mode[mode] = dentry; - } - - file = filp_open(LAST_RCVD, O_RDWR | O_CREAT, 0700); - if (!file || IS_ERR(file)) { - rc = PTR_ERR(file); - CERROR("OBD filter: cannot open/create %s: rc = %d\n", - LAST_RCVD, rc); - GOTO(err_O_mode, rc); - } - - if (!S_ISREG(file->f_dentry->d_inode->i_mode)) { - CERROR("%s is not a regular file!: mode = %o\n", LAST_RCVD, - file->f_dentry->d_inode->i_mode); - GOTO(err_filp, rc = -ENOENT); - } - - rc = fsfilt_journal_data(obd, file); - if (rc) { - CERROR("cannot journal data on %s: rc = %d\n", LAST_RCVD, rc); - GOTO(err_filp, 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; - - rc = filter_init_server_data(obd, file, INIT_OBJID); - if (rc) { - CERROR("cannot read %s: rc = %d\n", LAST_RCVD, rc); - GOTO(err_client, rc); - } - filter->fo_rcvd_filp = file; - - if (filter->fo_subdir_count) { - O_dentry = filter->fo_dentry_O_mode[S_IFREG >> S_SHIFT]; - OBD_ALLOC(filter->fo_dentry_O_sub, - FILTER_SUBDIR_COUNT * sizeof(dentry)); - if (!filter->fo_dentry_O_sub) - GOTO(err_client, rc = -ENOMEM); - - for (i = 0; i < filter->fo_subdir_count; i++) { - char dir[20]; - snprintf(dir, sizeof(dir), "d%u", i); - - dentry = simple_mkdir(O_dentry, dir, 0700); - CDEBUG(D_INODE, "got/created O/R/%s: %p\n", dir,dentry); - if (IS_ERR(dentry)) { - rc = PTR_ERR(dentry); - CERROR("can't create O/R/%s: rc = %d\n",dir,rc); - GOTO(err_O_sub, rc); - } - filter->fo_dentry_O_sub[i] = dentry; - } - } - rc = 0; - out: - pop_ctxt(&saved, &filter->fo_ctxt, NULL); - - return(rc); - -err_O_sub: - while (i-- > 0) { - struct dentry *dentry = filter->fo_dentry_O_sub[i]; - if (dentry) { - f_dput(dentry); - filter->fo_dentry_O_sub[i] = NULL; - } - } - OBD_FREE(filter->fo_dentry_O_sub, - filter->fo_subdir_count * sizeof(dentry)); -err_client: - class_disconnect_all(obd); -err_filp: - if (filp_close(file, 0)) - CERROR("can't close %s after error\n", LAST_RCVD); - filter->fo_rcvd_filp = NULL; -err_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; - } - } - 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; - long rc; - int mode; - - /* XXX: filter_update_lastobjid used to call fsync_dev. It might be - * best to start a transaction with h_sync, because we removed this - * from lastobjid */ - - push_ctxt(&saved, &filter->fo_ctxt, NULL); - rc = filter_update_server_data(filter->fo_rcvd_filp, filter->fo_fsd); - if (rc) - CERROR("OBD filter: error writing lastobjid: rc = %ld\n", rc); - - - if (filter->fo_rcvd_filp) { - rc = file_fsync(filter->fo_rcvd_filp, - filter->fo_rcvd_filp->f_dentry, 1); - filp_close(filter->fo_rcvd_filp, 0); - filter->fo_rcvd_filp = NULL; - if (rc) - CERROR("last_rcvd file won't closed rc = %ld\n", rc); - } - - if (filter->fo_subdir_count) { - int i; - for (i = 0; i < filter->fo_subdir_count; i++) { - struct dentry *dentry = filter->fo_dentry_O_sub[i]; - f_dput(dentry); - filter->fo_dentry_O_sub[i] = NULL; - } - OBD_FREE(filter->fo_dentry_O_sub, - filter->fo_subdir_count * - sizeof(*filter->fo_dentry_O_sub)); - } - 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); - filter_free_server_data(filter); - pop_ctxt(&saved, &filter->fo_ctxt, NULL); -} - - -static __u64 filter_next_id(struct obd_device *obd) -{ - obd_id id; - LASSERT(obd->u.filter.fo_fsd != NULL); - - spin_lock(&obd->u.filter.fo_objidlock); - id = le64_to_cpu(obd->u.filter.fo_fsd->fsd_last_objid); - obd->u.filter.fo_fsd->fsd_last_objid = cpu_to_le64(id + 1); - spin_unlock(&obd->u.filter.fo_objidlock); - - 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, int lockit) -{ - 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 id 0\n"); - LBUG(); - RETURN(ERR_PTR(-ESTALE)); - } - - len = sprintf(name, LPU64, id); - CDEBUG(D_INODE, "looking up object O/%*s/%s\n", - dparent->d_name.len, dparent->d_name.name, name); - if (lockit) - down(&dparent->d_inode->i_sem); - dchild = lookup_one_len(name, dparent, len); - if (lockit) - 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", - dparent->d_name.len, dparent->d_name.name, 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, obd_id objid) -{ - struct filter_obd *filter = &obd->u.filter; - - LASSERT((mode & S_IFMT) == S_IFREG); /* only regular files for now */ - if ((mode & S_IFMT) != S_IFREG || filter->fo_subdir_count == 0) - return filter->fo_dentry_O_mode[(mode & S_IFMT) >> S_SHIFT]; - - return filter->fo_dentry_O_sub[objid & (filter->fo_subdir_count - 1)]; -} - -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)); - } - - PORTAL_SLAB_ALLOC(ffd, filter_open_cache, sizeof(*ffd)); - 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)); - } - - push_ctxt(&saved, &filter->fo_ctxt, NULL); - file = filp_open(filter_id(name, filter, id, type), - O_RDWR | O_LARGEFILE, type); - pop_ctxt(&saved, &filter->fo_ctxt, NULL); - - if (IS_ERR(file)) { - CERROR("error opening %s: rc %ld\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 "LPU64"\n",id); - atomic_inc(&fdd->fdd_open_count); - } else { - atomic_set(&fdd->fdd_open_count, 1); - fdd->fdd_flags = 0; - fdd->fdd_objid = id; - /* 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; - LASSERT(file->private_data == NULL); - 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 "LPU64": rc = %p\n", id, file); - EXIT; -out: - return file; - -out_fdd: - kmem_cache_free(filter_dentry_cache, fdd); -out_ffd: - ffd->ffd_servercookie = DEAD_HANDLE_MAGIC; - PORTAL_SLAB_FREE(ffd, filter_open_cache, sizeof(*ffd)); - goto out; -} - -/* Caller must hold i_sem on dir_dentry->d_inode */ -/* Caller must push us into kernel context */ -static int filter_destroy_internal(struct obd_device *obd, - struct dentry *dir_dentry, - struct dentry *object_dentry) -{ - 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)); - } - - rc = vfs_unlink(dir_dentry->d_inode, object_dentry); - - 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_export *export, - struct filter_file_data *ffd, - struct obd_trans_info *oti) -{ - struct obd_device *obd = export->exp_obd; - struct filter_obd *filter = &obd->u.filter; - 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; - 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, fdd->fdd_objid); - struct obd_run_ctxt saved; - void *handle; - - down(&dir_dentry->d_inode->i_sem); - push_ctxt(&saved, &filter->fo_ctxt, NULL); - filter_start_transno(export); - handle = fsfilt_start(obd, dir_dentry->d_inode, - FSFILT_OP_UNLINK); - if (IS_ERR(handle)) { - rc = filter_finish_transno(export, handle, oti, - PTR_ERR(handle)); - GOTO(out, rc); - } - /* XXX unlink from PENDING directory now too */ - rc2 = filter_destroy_internal(obd, dir_dentry, object_dentry); - if (rc2 && !rc) - rc = rc2; - rc = filter_finish_transno(export, handle, oti, rc); - rc2 = fsfilt_commit(obd, dir_dentry->d_inode, handle); - if (rc2) { - CERROR("error on commit, err = %d\n", rc2); - if (!rc) - rc = rc2; - } - out: - pop_ctxt(&saved, &filter->fo_ctxt, NULL); - up(&dir_dentry->d_inode->i_sem); - } - - f_dput(object_dentry); - PORTAL_SLAB_FREE(ffd, filter_open_cache, sizeof(*ffd)); - - RETURN(rc); -} - -/* obd methods */ -/* mount the file system (secretly) */ -static int filter_common_setup(struct obd_device *obd, obd_count len, void *buf, - char *option) -{ - struct obd_ioctl_data* data = buf; - struct filter_obd *filter; - struct vfsmount *mnt; - int rc = 0; - ENTRY; - - if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2) - RETURN(-EINVAL); - - obd->obd_fsops = fsfilt_get_ops(data->ioc_inlbuf2); - if (IS_ERR(obd->obd_fsops)) - RETURN(PTR_ERR(obd->obd_fsops)); - - mnt = do_kern_mount(data->ioc_inlbuf2, 0, data->ioc_inlbuf1, option); - rc = PTR_ERR(mnt); - if (IS_ERR(mnt)) { - CERROR("mount of %s as type %s failed: rc %d\n", - data->ioc_inlbuf2, data->ioc_inlbuf1, rc); - GOTO(err_ops, rc); - } - -#if OST_RECOVERY - obd->obd_flags |= OBD_REPLAYABLE; -#endif - - 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; - CDEBUG(D_SUPER, "%s: mnt = %p\n", data->ioc_inlbuf1, mnt); - - 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(); - - rc = filter_prep(obd); - if (rc) - GOTO(err_kfree, rc); - -#ifdef FILTER_TRANSNO_SEM - init_MUTEX(&filter->fo_transno_sem); -#else - spin_lock_init(&filter->fo_translock); -#endif - 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) - GOTO(err_post, rc = -ENOMEM); - - ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL, - "filter_ldlm_cb_client", &obd->obd_ldlm_client); - - RETURN(0); - -err_post: - filter_post(obd); -err_kfree: - kfree(filter->fo_fstype); - unlock_kernel(); - mntput(filter->fo_vfsmnt); - filter->fo_sb = 0; - lock_kernel(); -err_ops: - fsfilt_put_ops(obd->obd_fsops); - return rc; -} - -static int filter_setup(struct obd_device *obd, obd_count len, void *buf) -{ - return filter_common_setup(obd, len, buf, NULL); -} - -/* sanobd setup methods - use a specific mount option */ -static int filter_san_setup(struct obd_device *obd, obd_count len, void *buf) -{ - struct obd_ioctl_data* data = buf; - char *option = NULL; - - if (!data->ioc_inlbuf2) - RETURN(-EINVAL); - - /* for extN/ext3 filesystem, we must mount it with 'writeback' mode */ - if (!strcmp(data->ioc_inlbuf2, "extN") || - !strcmp(data->ioc_inlbuf2, "ext3")) - option = "data=writeback"; - else - LBUG(); /* just a reminder */ - - return filter_common_setup(obd, len, buf, option); -} - -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); - fsfilt_put_ops(obd->obd_fsops); - - lock_kernel(); - - RETURN(0); -} - -int filter_attach(struct obd_device *dev, obd_count len, void *data) -{ - struct lprocfs_static_vars lvars; - - lprocfs_init_vars(&lvars); - return lprocfs_obd_attach(dev, lvars.obd_vars); -} - -int filter_detach(struct obd_device *dev) -{ - return lprocfs_obd_detach(dev); -} - -/* nearly identical to mds_connect */ -static int filter_connect(struct lustre_handle *conn, struct obd_device *obd, - struct obd_uuid *cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct obd_export *exp; - struct filter_export_data *fed; - struct filter_client_data *fcd; - struct filter_obd *filter = &obd->u.filter; - int rc; - - ENTRY; - - if (!conn || !obd || !cluuid) - RETURN(-EINVAL); - - rc = class_connect(conn, obd, cluuid); - if (rc) - RETURN(rc); - exp = class_conn2export(conn); - LASSERT(exp); - fed = &exp->exp_filter_data; - - OBD_ALLOC(fcd, sizeof(*fcd)); - if (!fcd) { - CERROR("filter: out of memory for client data\n"); - GOTO(out_export, rc = -ENOMEM); - } - - memcpy(fcd->fcd_uuid, cluuid, sizeof(fcd->fcd_uuid)); - fed->fed_fcd = fcd; - fcd->fcd_mount_count = cpu_to_le64(filter->fo_fsd->fsd_mount_count); - - INIT_LIST_HEAD(&exp->exp_filter_data.fed_open_head); - spin_lock_init(&exp->exp_filter_data.fed_lock); - - if (obd->obd_flags & OBD_REPLAYABLE) { - rc = filter_client_add(filter, fed, -1); - if (rc) - GOTO(out_fcd, rc); - } - - RETURN(rc); - -out_fcd: - OBD_FREE(fcd, sizeof(*fcd)); -out_export: - class_disconnect(conn); - - RETURN(rc); -} - -/* also incredibly similar to mds_disconnect */ -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 close file %*s (hdl %p:"LPX64") on disconnect\n", - ffd->ffd_file->f_dentry->d_name.len, - ffd->ffd_file->f_dentry->d_name.name, - ffd, ffd->ffd_servercookie); - - filter_close_internal(exp, ffd, NULL); - spin_lock(&fed->fed_lock); - } - spin_unlock(&fed->fed_lock); - - ldlm_cancel_locks_for_export(exp); - - if (exp->exp_obd->obd_flags & OBD_REPLAYABLE) - filter_client_free(exp); - - rc = class_disconnect(conn); - - /* XXX cleanup preallocated inodes */ - RETURN(rc); -} - -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 %lu (%p), dst obdo "LPU64" valid 0x%08x\n", - inode->i_ino, inode, 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_id, locked); - } - - if (IS_ERR(dentry)) { - CERROR("%s error looking up object: "LPU64"\n", what, oa->o_id); - RETURN(dentry); - } - - if (!dentry->d_inode) { - CERROR("%s on non-existent object: "LPU64"\n", what, oa->o_id); - f_dput(dentry); - LBUG(); - 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; - - XPROCFS_BUMP_MYCPU_IOSTAT (st_getattr_reqs, 1); - - dentry = filter_oa2dentry(conn, oa, 1); - if (IS_ERR(dentry)) - RETURN(PTR_ERR(dentry)); - - filter_from_inode(oa, dentry->d_inode, oa->o_valid); - - f_dput(dentry); - RETURN(rc); -} - -/* this is called from filter_truncate() until we have filter_punch() */ -static int filter_setattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md, struct obd_trans_info *oti) -{ - struct obd_run_ctxt saved; - struct obd_export *export = class_conn2export(conn); - struct obd_device *obd = class_conn2obd(conn); - struct filter_obd *filter = &obd->u.filter; - struct dentry *dentry; - struct iattr iattr; - struct inode *inode; - void * handle; - int rc, rc2; - ENTRY; - - XPROCFS_BUMP_MYCPU_IOSTAT (st_setattr_reqs, 1); - - 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; - - push_ctxt(&saved, &filter->fo_ctxt, NULL); - lock_kernel(); - if (iattr.ia_valid & ATTR_SIZE) - down(&inode->i_sem); - - filter_start_transno(export); - handle = fsfilt_start(obd, dentry->d_inode, FSFILT_OP_SETATTR); - if (IS_ERR(handle)) { - rc = filter_finish_transno(export, handle, oti,PTR_ERR(handle)); - GOTO(out_unlock, rc); - } - - if (inode->i_op->setattr) - rc = inode->i_op->setattr(dentry, &iattr); - else - rc = inode_setattr(inode, &iattr); - rc = filter_finish_transno(export, handle, oti, rc); - rc2 = fsfilt_commit(obd, dentry->d_inode, handle); - if (rc2) { - CERROR("error on commit, err = %d\n", rc2); - if (!rc) - rc = rc2; - } - - 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); - } - -out_unlock: - unlock_kernel(); - pop_ctxt(&saved, &filter->fo_ctxt, NULL); - - f_dput(dentry); - RETURN(rc); -} - -static int filter_open(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea, struct obd_trans_info *oti) -{ - 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); - } - - XPROCFS_BUMP_MYCPU_IOSTAT (st_open_reqs, 1); - - 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_trans_info *oti) -{ - 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); - } - - XPROCFS_BUMP_MYCPU_IOSTAT (st_close_reqs, 1); - - if (!(oa->o_valid & OBD_MD_FLHANDLE)) { - CERROR("no handle for close of objid "LPU64"\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, ffd, oti); - - RETURN(rc); -} /* filter_close */ - -static int filter_create(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md **ea, struct obd_trans_info *oti) -{ - struct obd_export *export = class_conn2export(conn); - struct obd_device *obd = class_conn2obd(conn); - struct filter_obd *filter = &obd->u.filter; - struct obd_run_ctxt saved; - struct dentry *dir_dentry; - struct dentry *new; - struct iattr; - void *handle; - int err, rc; - ENTRY; - - if (!obd) { - CERROR("invalid client "LPX64"\n", conn->addr); - return -EINVAL; - } - - XPROCFS_BUMP_MYCPU_IOSTAT (st_create_reqs, 1); - - oa->o_id = filter_next_id(obd); - - push_ctxt(&saved, &filter->fo_ctxt, NULL); - dir_dentry = filter_parent(obd, S_IFREG, oa->o_id); - down(&dir_dentry->d_inode->i_sem); - new = filter_fid2dentry(obd, dir_dentry, oa->o_id, 0); - if (IS_ERR(new)) - GOTO(out, rc = PTR_ERR(new)); - - if (new->d_inode) { - char buf[32]; - - /* This would only happen if lastobjid was bad on disk */ - CERROR("objid %s already exists\n", - filter_id(buf, filter, S_IFREG, oa->o_id)); - LBUG(); - GOTO(out, rc = -EEXIST); - } - - filter_start_transno(export); - handle = fsfilt_start(obd, dir_dentry->d_inode, FSFILT_OP_CREATE); - if (IS_ERR(handle)) { - rc = filter_finish_transno(export, handle, oti,PTR_ERR(handle)); - GOTO(out_put, rc); - } - rc = vfs_create(dir_dentry->d_inode, new, oa->o_mode); - if (rc) - CERROR("create failed rc = %d\n", rc); - - rc = filter_finish_transno(export, handle, oti, rc); - err = filter_update_server_data(filter->fo_rcvd_filp, filter->fo_fsd); - if (err) { - CERROR("unable to write lastobjid but file created\n"); - if (!rc) - rc = err; - } - err = fsfilt_commit(obd, dir_dentry->d_inode, handle); - if (err) { - CERROR("error on commit, err = %d\n", err); - if (!rc) - rc = err; - } - - if (rc) - GOTO(out_put, rc); - - /* 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); - - EXIT; -out_put: - f_dput(new); -out: - up(&dir_dentry->d_inode->i_sem); - pop_ctxt(&saved, &filter->fo_ctxt, NULL); - return rc; -} - -static int filter_destroy(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *ea, struct obd_trans_info *oti) -{ - struct obd_export *export = class_conn2export(conn); - struct obd_device *obd = class_conn2obd(conn); - struct filter_obd *filter = &obd->u.filter; - struct dentry *dir_dentry, *object_dentry; - struct filter_dentry_data *fdd; - struct obd_run_ctxt saved; - void *handle; - int rc, rc2; - ENTRY; - - if (!obd) { - CERROR("invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - XPROCFS_BUMP_MYCPU_IOSTAT (st_destroy_reqs, 1); - - CDEBUG(D_INODE, "destroying objid "LPU64"\n", oa->o_id); - - dir_dentry = filter_parent(obd, oa->o_mode, oa->o_id); - down(&dir_dentry->d_inode->i_sem); - - object_dentry = filter_oa2dentry(conn, oa, 0); - if (IS_ERR(object_dentry)) - GOTO(out, rc = -ENOENT); - - push_ctxt(&saved, &filter->fo_ctxt, NULL); - filter_start_transno(export); - handle = fsfilt_start(obd, dir_dentry->d_inode, FSFILT_OP_UNLINK); - if (IS_ERR(handle)) { - rc = filter_finish_transno(export, handle, oti,PTR_ERR(handle)); - GOTO(out_ctxt, rc); - } - - 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 "LPU64"\n", - atomic_read(&fdd->fdd_open_count), oa->o_id); - } else - CDEBUG(D_INODE, - "repeat destroy of %dx open objid "LPU64"\n", - atomic_read(&fdd->fdd_open_count), oa->o_id); - GOTO(out_commit, rc = 0); - } - - rc = filter_destroy_internal(obd, dir_dentry, object_dentry); - -out_commit: - /* XXX save last_rcvd on disk */ - rc = filter_finish_transno(export, handle, oti, rc); - rc2 = fsfilt_commit(obd, dir_dentry->d_inode, handle); - if (rc2) { - CERROR("error on commit, err = %d\n", rc2); - if (!rc) - rc = rc2; - } -out_ctxt: - pop_ctxt(&saved, &filter->fo_ctxt, NULL); - f_dput(object_dentry); - - EXIT; -out: - up(&dir_dentry->d_inode->i_sem); - return rc; -} - -/* NB start and end 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, - struct obd_trans_info *oti) -{ - int error; - ENTRY; - - XPROCFS_BUMP_MYCPU_IOSTAT (st_punch_reqs, 1); - - if (end != OBD_OBJECT_EOF) - CERROR("PUNCH not supported, only truncate works\n"); - - CDEBUG(D_INODE, "calling truncate for object "LPU64", valid = %x, " - "o_size = "LPD64"\n", oa->o_id, oa->o_valid, start); - oa->o_size = start; - error = filter_setattr(conn, oa, NULL, oti); - RETURN(error); -} - -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_local *lnb) -{ - unsigned long index = lnb->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); - lnb->addr = kmap(page); - lnb->page = 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 - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -/* We should only change the file mtime (and not the ctime, like - * update_inode_times() in generic_file_write()) when we only change data. - */ -static inline void inode_update_time(struct inode *inode, int ctime_too) -{ - time_t now = CURRENT_TIME; - if (inode->i_mtime == now && (!ctime_too || inode->i_ctime == now)) - return; - inode->i_mtime = now; - if (ctime_too) - inode->i_ctime = now; - mark_inode_dirty_sync(inode); -} -#endif - -static int lustre_commit_write(struct niobuf_local *lnb) -{ - struct page *page = lnb->page; - unsigned from = lnb->offset & ~PAGE_MASK; - unsigned to = from + lnb->len; - struct inode *inode = page->mapping->host; - int err; - - LASSERT(to <= PAGE_SIZE); - 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_local *lnb, int *pglocked) -{ - unsigned long index = lnb->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_ERROR,"ino %lu 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"); - GOTO(err, rc = -ENOMEM); - } - POISON((void *)addr, 0xBA, PAGE_SIZE); - page = virt_to_page(addr); - kmap(page); - page->index = index; - lnb->addr = (void *)addr; - lnb->page = page; - lnb->flags |= N_LOCAL_TEMP_PAGE; - } else if (!IS_ERR(page)) { - (*pglocked)++; - kmap(page); - - rc = mapping->a_ops->prepare_write(NULL, page, - lnb->offset & ~PAGE_MASK, - lnb->len); - if (rc) { - if (rc != -ENOSPC) - CERROR("page index %lu, rc = %d\n", index, rc); - 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); - } - lnb->addr = page_address(page); - lnb->page = page; - } - - 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 niobuf_local *lnb, int err) -{ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - if (err) { - unsigned block_start, block_end; - struct buffer_head *bh, *head = lnb->page->buffers; - unsigned blocksize = head->b_size; - - /* debugging: just seeing if this ever happens */ - CDEBUG(err == -ENOSPC ? D_INODE : D_ERROR, - "called for ino %lu:%lu on err %d\n", - lnb->page->mapping->host->i_ino, lnb->page->index, 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(lnb->addr + block_start, 0, blocksize); - } - } -#endif - return lustre_commit_write(lnb); -} - -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_trans_info *oti) -{ - struct obd_run_ctxt saved; - struct obd_export *export; - struct obd_device *obd; - struct obd_ioobj *o; - struct niobuf_remote *rnb = nb; - struct niobuf_local *lnb = res; - struct fsfilt_objinfo *fso; - int pglocked = 0; - int rc = 0; - int i; - ENTRY; - - if ((cmd & OBD_BRW_WRITE) != 0) - XPROCFS_BUMP_MYCPU_IOSTAT (st_write_reqs, 1); - else - XPROCFS_BUMP_MYCPU_IOSTAT (st_read_reqs, 1); - - memset(res, 0, niocount * sizeof(*res)); - - export = class_conn2export(conn); - obd = class_conn2obd(conn); - if (!obd) { - CDEBUG(D_IOCTL, "invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - LASSERT(objcount < 16); // theoretically we support multi-obj BRW - - OBD_ALLOC(fso, objcount * sizeof(*fso)); - if (!fso) - RETURN(-ENOMEM); - - push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - - for (i = 0, o = obj; i < objcount; i++, o++) { - struct filter_dentry_data *fdd; - struct dentry *dentry; - - LASSERT(o->ioo_bufcnt); - - dentry = filter_fid2dentry(obd, filter_parent(obd, S_IFREG, - o->ioo_id), - o->ioo_id, 0); - - if (IS_ERR(dentry)) - GOTO(out_objinfo, rc = PTR_ERR(dentry)); - - fso[i].fso_dentry = dentry; - fso[i].fso_bufcnt = o->ioo_bufcnt; - - if (!dentry->d_inode) { - CERROR("trying to BRW to non-existent file "LPU64"\n", - o->ioo_id); - f_dput(dentry); - GOTO(out_objinfo, rc = -ENOENT); - } - - fdd = dentry->d_fsdata; - if (!fdd || !atomic_read(&fdd->fdd_open_count)) - CDEBUG(D_PAGE, "I/O to unopened object "LPU64"\n", - o->ioo_id); - } - - if (cmd & OBD_BRW_WRITE) { -#warning "FIXME: we need inode->i_sem for each object to protect vs truncate" - /* Even worse, we need to get locks on mulitple inodes (in - * order) or use the DLM to do the locking for us (and use - * the same locking in filter_setattr() for truncate. The - * handling gets very ugly when dealing with locked pages. - * It may be easier to just get rid of the locked page code - * (which has problems of its own) and either discover we do - * not need it anymore (i.e. it was a symptom of another bug) - * or ensure we get the page locks in an appropriate order. - */ - /* Danger, Will Robinson! You are taking a lock here and also - * starting a transaction and releasing/finishing then in - * filter_commitrw(), so you must call fsfilt_commit() and - * finish_transno() if an error occurs in this function. - */ - filter_start_transno(export); - *desc_private = fsfilt_brw_start(obd, objcount, fso, - niocount, nb); - if (IS_ERR(*desc_private)) { - rc = PTR_ERR(*desc_private); - CDEBUG(rc == -ENOSPC ? D_INODE : D_ERROR, - "error starting transaction: rc = %d\n", rc); - *desc_private = NULL; - GOTO(out_objinfo, rc); - } - } - - obd_kmap_get(niocount, 1); - - for (i = 0, o = obj; i < objcount; i++, o++) { - struct dentry *dentry; - struct inode *inode; - int j; - - dentry = fso[i].fso_dentry; - inode = dentry->d_inode; - - for (j = 0; j < o->ioo_bufcnt; j++, rnb++, lnb++) { - struct page *page; - - if (j == 0) - lnb->dentry = dentry; - else - lnb->dentry = dget(dentry); - - /* lnb->offset is aligned, while rnb->offset isn't, - * and we need to copy the fields to lnb anyways. - */ - memcpy(lnb, rnb, sizeof(*rnb)); - if (cmd & OBD_BRW_WRITE) { - page = filter_get_page_write(inode, lnb, - &pglocked); - - XPROCFS_BUMP_MYCPU_IOSTAT(st_write_bytes, - lnb->len); - } else { - page = lustre_get_page_read(inode, lnb); - - XPROCFS_BUMP_MYCPU_IOSTAT(st_read_bytes, - lnb->len); - } - - if (IS_ERR(page)) { - rc = PTR_ERR(page); - CDEBUG(rc == -ENOSPC ? D_INODE : D_ERROR, - "error on page @"LPU64"%u/%u: rc = %d\n", - lnb->offset, j, o->ioo_bufcnt, rc); - f_dput(dentry); - GOTO(out_pages, rc); - } - } - } - - EXIT; -out: - OBD_FREE(fso, objcount * sizeof(*fso)); - current->journal_info = NULL; - pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - return rc; - -out_pages: - while (lnb-- > res) { - if (cmd & OBD_BRW_WRITE) - filter_commit_write(lnb, rc); - else - lustre_put_page(lnb->page); - f_dput(lnb->dentry); - } - obd_kmap_put(niocount); - if (cmd & OBD_BRW_WRITE) { - filter_finish_transno(export, *desc_private, oti, rc); - fsfilt_commit(obd, - filter_parent(obd,S_IFREG,obj->ioo_id)->d_inode, - *desc_private); - } - goto out; /* dropped the dentry refs already (one per page) */ - -out_objinfo: - for (i = 0; i < objcount && fso[i].fso_dentry; i++) - f_dput(fso[i].fso_dentry); - goto out; -} - -static int filter_write_locked_page(struct niobuf_local *lnb) -{ - struct page *lpage; - int rc; - ENTRY; - - 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); - LBUG(); - lustre_commit_write(lnb); - RETURN(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); - lustre_put_page(lnb->page); - - lnb->page = lpage; - rc = lustre_commit_write(lnb); - if (rc) - CERROR("error committing locked page %ld: rc = %d\n", - lnb->page->index, rc); - - RETURN(rc); -} - -static int filter_syncfs(struct lustre_handle *conn) -{ - struct obd_device *obd; - ENTRY; - - obd = class_conn2obd(conn); - - XPROCFS_BUMP_MYCPU_IOSTAT (st_syncfs_reqs, 1); - - RETURN(fsfilt_sync(obd, obd->u.filter.fo_sb)); -} - -static int filter_commitrw(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_local *res, - void *desc_private, struct obd_trans_info *oti) -{ - struct obd_run_ctxt saved; - struct obd_ioobj *o; - struct niobuf_local *lnb; - struct obd_export *export = class_conn2export(conn); - struct obd_device *obd = class_conn2obd(conn); - int found_locked = 0; - int rc = 0; - int i; - ENTRY; - - push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - - LASSERT(!current->journal_info); - current->journal_info = desc_private; - - for (i = 0, o = obj, lnb = res; i < objcount; i++, o++) { - int j; - - if (cmd & OBD_BRW_WRITE) - inode_update_time(lnb->dentry->d_inode, 1); - for (j = 0 ; j < o->ioo_bufcnt ; j++, lnb++) { - if (lnb->flags & N_LOCAL_TEMP_PAGE) { - found_locked++; - continue; - } - - if (cmd & OBD_BRW_WRITE) { - int err = filter_commit_write(lnb, 0); - - if (!rc) - rc = err; - } else - lustre_put_page(lnb->page); - - obd_kmap_put(1); - f_dput(lnb->dentry); - } - } - - for (i = 0, o = obj, lnb = res; found_locked > 0 && i < objcount; - i++, o++) { - int j; - for (j = 0 ; j < o->ioo_bufcnt ; j++, lnb++) { - int err; - if (!(lnb->flags & N_LOCAL_TEMP_PAGE)) - continue; - - err = filter_write_locked_page(lnb); - obd_kmap_put(1); - if (!rc) - rc = err; - f_dput(lnb->dentry); - found_locked--; - } - } - - if (cmd & OBD_BRW_WRITE) { - /* We just want any dentry for the commit, for now */ - struct dentry *dir_dentry = filter_parent(obd, S_IFREG, 0); - int err; - - rc = filter_finish_transno(export, desc_private, oti, rc); - err = fsfilt_commit(obd, dir_dentry->d_inode, desc_private); - if (err) - rc = err; - if (obd_sync_filter) { - /* this can fail with ENOMEM, what should we do then? */ - filter_syncfs(conn); - } - /* XXX LASSERT(last_rcvd == last_committed)*/ - } - - LASSERT(!current->journal_info); - - pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); - RETURN(rc); -} - -static int filter_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_trans_info *oti) -{ - struct obd_ioobj ioo; - struct niobuf_local *lnb; - struct niobuf_remote *rnb; - obd_count i; - void *desc_private; - int ret = 0; - ENTRY; - - OBD_ALLOC(lnb, oa_bufs * sizeof(struct niobuf_local)); - OBD_ALLOC(rnb, oa_bufs * sizeof(struct niobuf_remote)); - - if (lnb == NULL || rnb == NULL) - GOTO(out, ret = -ENOMEM); - - for (i = 0; i < oa_bufs; i++) { - rnb[i].offset = pga[i].off; - rnb[i].len = pga[i].count; - } - - ioo.ioo_id = lsm->lsm_object_id; - ioo.ioo_gr = 0; - ioo.ioo_type = S_IFREG; - ioo.ioo_bufcnt = oa_bufs; - - ret = filter_preprw(cmd, conn, 1, &ioo, oa_bufs, rnb, lnb, - &desc_private, oti); - if (ret != 0) - GOTO(out, ret); - - for (i = 0; i < oa_bufs; i++) { - void *virt = kmap(pga[i].pg); - obd_off off = pga[i].off & ~PAGE_MASK; - - if (cmd & OBD_BRW_WRITE) - memcpy(lnb[i].addr + off, virt + off, pga[i].count); - else - memcpy(virt + off, lnb[i].addr + off, pga[i].count); - - kunmap(virt); - } - - ret = filter_commitrw(cmd, conn, 1, &ioo, oa_bufs, lnb, desc_private, - oti); - -out: - if (lnb) - OBD_FREE(lnb, oa_bufs * sizeof(struct niobuf_local)); - if (rnb) - OBD_FREE(rnb, oa_bufs * sizeof(struct niobuf_remote)); - RETURN(ret); -} - -static int filter_san_preprw(int cmd, struct lustre_handle *conn, - int objcount, struct obd_ioobj *obj, - int niocount, struct niobuf_remote *nb) -{ - struct obd_device *obd; - struct obd_ioobj *o = obj; - struct niobuf_remote *rnb = nb; - int rc = 0; - int i; - ENTRY; - - if ((cmd & OBD_BRW_WRITE) != 0) - XPROCFS_BUMP_MYCPU_IOSTAT (st_write_reqs, 1); - else - XPROCFS_BUMP_MYCPU_IOSTAT (st_read_reqs, 1); - - obd = class_conn2obd(conn); - if (!obd) { - CDEBUG(D_IOCTL, "invalid client "LPX64"\n", conn->addr); - RETURN(-EINVAL); - } - - 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), - o->ioo_id, 0); - if (IS_ERR(dentry)) - GOTO(out, 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, rc = -ENOENT); - } - - for (j = 0; j < o->ioo_bufcnt; j++, rnb++) { - long block; - - block = rnb->offset >> PAGE_SHIFT; - - if (cmd == OBD_BRW_READ) { - block = inode->i_mapping->a_ops->bmap( - inode->i_mapping, block); - } else { - loff_t newsize = rnb->offset + rnb->len; - /* fs_prep_san_write will also update inode - * size for us: - * (1) new alloced block - * (2) existed block but size extented - */ - /* FIXME We could call fs_prep_san_write() - * only once for all the blocks allocation. - * Now call it once for each block, for - * simplicity. And if error happens, we - * probably need to release previous alloced - * block */ - rc = fs_prep_san_write(obd, inode, &block, - 1, newsize); - if (rc) - break; - } - - rnb->offset = block; - } - f_dput(dentry); - } -out: - RETURN(rc); -} - -static int filter_statfs(struct lustre_handle *conn, struct obd_statfs *osfs) -{ - struct obd_device *obd; - ENTRY; - - obd = class_conn2obd(conn); - - XPROCFS_BUMP_MYCPU_IOSTAT (st_statfs_reqs, 1); - - RETURN(fsfilt_statfs(obd, obd->u.filter.fo_sb, osfs)); -} - -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); - } - - 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 obd_trans_info *oti) -{ - 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,NULL); - 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,oti); - 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); -} - -static struct obd_ops filter_obd_ops = { - o_owner: THIS_MODULE, - 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_syncfs: filter_syncfs, - 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_brw, - o_punch: filter_truncate, - o_preprw: filter_preprw, - o_commitrw: filter_commitrw -#if 0 - o_san_preprw: filter_san_preprw, - o_preallocate: filter_preallocate_inodes, - o_migrate: filter_migrate, - o_copy: filter_copy_data, - o_iterate: filter_iterate -#endif -}; - -static struct obd_ops filter_sanobd_ops = { - o_owner: THIS_MODULE, - o_attach: filter_attach, - o_detach: filter_detach, - o_get_info: filter_get_info, - o_setup: filter_san_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_brw, - o_punch: filter_truncate, - o_preprw: filter_preprw, - o_commitrw: filter_commitrw, - o_san_preprw: filter_san_preprw, -#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) -{ - struct lprocfs_static_vars lvars; - int rc; - - printk(KERN_INFO "Lustre Filtering OBD driver; 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) { - rc = -ENOMEM; - goto err1; - } - - xprocfs_init ("filter"); - - lprocfs_init_vars(&lvars); - - rc = class_register_type(&filter_obd_ops, lvars.module_vars, - OBD_FILTER_DEVICENAME); - if (rc) - goto err2; - - rc = class_register_type(&filter_sanobd_ops, lvars.module_vars, - OBD_FILTER_SAN_DEVICENAME); - if (rc) - goto err3; - - return 0; -err3: - class_unregister_type(OBD_FILTER_DEVICENAME); -err2: - kmem_cache_destroy(filter_dentry_cache); -err1: - kmem_cache_destroy(filter_open_cache); - return rc; -} - -static void __exit obdfilter_exit(void) -{ - class_unregister_type(OBD_FILTER_SAN_DEVICENAME); - 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"); - xprocfs_fini (); -} - -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Filtering OBD driver"); -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 c4e0747..0000000 --- a/lustre/obdfilter/lproc_obdfilter.c +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_CLASS - -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#endif -#include -#include - -#ifndef LPROCFS -struct lprocfs_vars lprocfs_obd_vars[] = { {0} }; -struct lprocfs_vars lprocfs_module_vars[] = { {0} }; -#else - -static inline int lprocfs_filter_statfs(void *data, struct statfs *sfs) -{ - struct obd_device *dev = (struct obd_device *) data; - LASSERT(dev != NULL); - return vfs_statfs(dev->u.filter.fo_sb, sfs); -} - -DEFINE_LPROCFS_STATFS_FCT(rd_blksize, lprocfs_filter_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_kbytestotal, lprocfs_filter_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_kbytesfree, lprocfs_filter_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filestotal, lprocfs_filter_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filesfree, lprocfs_filter_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filegroups, lprocfs_filter_statfs); - -int rd_fstype(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - struct obd_device *dev = (struct obd_device *)data; - LASSERT(dev != NULL); - return snprintf(page, count, "%s\n", dev->u.filter.fo_fstype); -} - -struct lprocfs_vars lprocfs_obd_vars[] = { - { "uuid", lprocfs_rd_uuid, 0, 0 }, - { "blocksize", rd_blksize, 0, 0 }, - { "kbytestotal", rd_kbytestotal, 0, 0 }, - { "kbytesfree", rd_kbytesfree, 0, 0 }, - { "filestotal", rd_filestotal, 0, 0 }, - { "filesfree", rd_filesfree, 0, 0 }, - { "filegroups", rd_filegroups, 0, 0 }, - { "fstype", rd_fstype, 0, 0 }, - { 0 } -}; - -struct lprocfs_vars lprocfs_module_vars[] = { - { "num_refs", lprocfs_rd_numrefs, 0, 0 }, - { 0 } -}; - -#endif /* LPROCFS */ -LPROCFS_INIT_VARS(lprocfs_module_vars, lprocfs_obd_vars) 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 19fd65c..0000000 --- a/lustre/osc/Makefile.am +++ /dev/null @@ -1,29 +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 LIBLUSTRE -lib_LIBRARIES = libosc.a -LINX= obd_pack.c client.c -libosc_a_SOURCES = osc_request.c $(LINX) -else -MODULE = osc -modulefs_DATA = osc.o -EXTRA_PROGRAMS = osc -LINX= obd_pack.c client.c -osc_SOURCES = osc_request.c lproc_osc.c $(LINX) -endif - -obd_pack.c: - test -e obd_pack.c || ln -sf $(top_srcdir)/lib/obd_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 d5e4ec1..0000000 --- a/lustre/osc/lproc_osc.c +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_CLASS - -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#endif -#include -#include - -#ifndef LPROCFS -struct lprocfs_vars lprocfs_obd_vars[] = { {0} }; -struct lprocfs_vars lprocfs_module_vars[] = { {0} }; -#else - -DEFINE_LPROCFS_STATFS_FCT(rd_blksize, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_kbytestotal, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_kbytesfree, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filestotal, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filesfree, obd_self_statfs); -DEFINE_LPROCFS_STATFS_FCT(rd_filegroups, obd_self_statfs); - -struct lprocfs_vars lprocfs_obd_vars[] = { - { "uuid", lprocfs_rd_uuid, 0, 0 }, - { "blocksize", rd_blksize, 0, 0 }, - { "kbytestotal", rd_kbytestotal, 0, 0 }, - { "kbytesfree", rd_kbytesfree, 0, 0 }, - { "filestotal", rd_filestotal, 0, 0 }, - { "filesfree", rd_filesfree, 0, 0 }, - { "filegroups", rd_filegroups, 0, 0 }, - { "ost_server_uuid", lprocfs_rd_server_uuid, 0, 0 }, - { "ost_conn_uuid", lprocfs_rd_conn_uuid, 0, 0 }, - { 0 } -}; - -struct lprocfs_vars lprocfs_module_vars[] = { - { "num_refs", lprocfs_rd_numrefs, 0, 0 }, - { 0 } -}; - -#endif /* LPROCFS */ -LPROCFS_INIT_VARS(lprocfs_module_vars, lprocfs_obd_vars) diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c deleted file mode 100644 index ea205a6..0000000 --- a/lustre/osc/osc_request.c +++ /dev/null @@ -1,1675 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2001-2003 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 - -#ifdef __KERNEL__ -#include -#include -#include -#include -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -#include -#include -#else -#include -#endif -#else -#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 - -/* It is important that ood_fh remain the first item in this structure: that - * way, we don't have to re-pack the obdo's inline data before we send it to - * the server, we can just send the whole struct unaltered. */ -#define OSC_OBDO_DATA_MAGIC 0xD15EA5ED -struct osc_obdo_data { - struct lustre_handle ood_fh; - struct ptlrpc_request *ood_request; - __u32 ood_magic; -}; -#include /* just for the startup assertion; is that wrong? */ - -static int send_sync(struct obd_import *imp, struct ll_fid *rootfid, - int level, int msg_flags) -{ - struct ptlrpc_request *req; - struct mds_body *body; - int rc, size = sizeof(*body); - ENTRY; - - req = ptlrpc_prep_req(imp, OST_SYNCFS, 1, &size, NULL); - if (!req) - GOTO(out, rc = -ENOMEM); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - req->rq_level = level; - req->rq_replen = lustre_msg_size(1, &size); - - req->rq_reqmsg->flags |= msg_flags; - rc = ptlrpc_queue_wait(req); - - if (!rc) { - CDEBUG(D_NET, "last_committed="LPU64 - ", last_xid="LPU64"\n", - req->rq_repmsg->last_committed, - req->rq_repmsg->last_xid); - } - - EXIT; - out: - ptlrpc_req_finished(req); - return rc; -} - -static int signal_completed_replay(struct obd_import *imp) -{ - struct ll_fid fid; - - return send_sync(imp, &fid, LUSTRE_CONN_RECOVD, MSG_LAST_REPLAY); -} - -static int osc_attach(struct obd_device *dev, obd_count len, void *data) -{ - struct lprocfs_static_vars lvars; - - lprocfs_init_vars(&lvars); - return lprocfs_obd_attach(dev, lvars.obd_vars); -} - -static int osc_detach(struct obd_device *dev) -{ - return lprocfs_obd_detach(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; - ENTRY; - - 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; - ENTRY; - - 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); -} - -inline void oti_from_request(struct obd_trans_info *oti, - struct ptlrpc_request *req) -{ - if (oti && req->rq_repmsg) - oti->oti_transno = NTOH__u64(req->rq_repmsg->transno); - EXIT; -} - -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); - 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 obd_trans_info *oti) -{ - 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); - - request->rq_flags |= PTL_RPC_FL_REPLAY; - 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); - - if (oa) { - struct osc_obdo_data ood; - body = lustre_msg_buf(request->rq_repmsg, 0); - memcpy(oa, &body->oa, sizeof(*oa)); - - /* If the open succeeded, we better have a handle */ - /* BlueArc OSTs don't send back (o_valid | FLHANDLE). sigh. - * Temporary workaround until fixed. -phil 24 Feb 03 */ - //LASSERT(oa->o_valid & OBD_MD_FLHANDLE); - oa->o_valid |= OBD_MD_FLHANDLE; - - memcpy(&ood.ood_fh, obdo_handle(oa), sizeof(ood.ood_fh)); - ood.ood_request = ptlrpc_request_addref(request); - ood.ood_magic = OSC_OBDO_DATA_MAGIC; - - /* Save this data in the request; it will be passed back to us - * in future obdos. This memcpy is guaranteed to be safe, - * because we check at compile-time that sizeof(ood) is smaller - * than oa->o_inline. */ - memcpy(&oa->o_inline, &ood, sizeof(ood)); - } - - 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 obd_trans_info *oti) -{ - struct obd_import *import = class_conn2cliimp(conn); - struct ptlrpc_request *request; - struct ost_body *body; - struct osc_obdo_data *ood; - unsigned long flags; - int rc, size = sizeof(*body); - ENTRY; - - LASSERT(oa != NULL); - ood = (struct osc_obdo_data *)&oa->o_inline; - LASSERT(ood->ood_magic == OSC_OBDO_DATA_MAGIC); - - request = ptlrpc_prep_req(import, 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) { - /* FIXME: Does this mean that the file is still open locally? - * If not, and I somehow suspect not, we need to cleanup - * below */ - GOTO(out, rc); - } - - spin_lock_irqsave(&import->imp_lock, flags); - ood->ood_request->rq_flags &= ~PTL_RPC_FL_REPLAY; - /* see comments in llite/file.c:ll_mdc_close() */ - if (ood->ood_request->rq_transno) { - LBUG(); /* this can't happen yet */ - if (!request->rq_transno) { - request->rq_transno = ood->ood_request->rq_transno; - ptlrpc_retain_replayable_request(request, import); - } - spin_unlock_irqrestore(&import->imp_lock, flags); - } else { - spin_unlock_irqrestore(&import->imp_lock, flags); - ptlrpc_req_finished(ood->ood_request); - } - - 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_setattr(struct lustre_handle *conn, struct obdo *oa, - struct lov_stripe_md *md, struct obd_trans_info *oti) -{ - 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 obd_trans_info *oti_in) -{ - struct ptlrpc_request *request; - struct ost_body *body; - struct lov_stripe_md *lsm; - struct obd_trans_info *oti, trans_info; - 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); - } - - if (oti_in) - oti = oti_in; - else - oti = &trans_info; - - 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; - - oti_from_request(oti, request); - CDEBUG(D_HA, "transno: "LPD64"\n", oti->oti_transno); - 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 obd_trans_info *oti) -{ - 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 obd_trans_info *oti) -{ - 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; - - 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; -} - -/* - * This is called when there was a bulk error return. However, we don't know - * whether the bulk completed or not. We cancel the portals bulk descriptors, - * so that if the OST decides to send them later we don't double free. Then - * remove this descriptor from the set so that the set callback doesn't wait - * forever for the last CB_PHASE_FINISH to be called, and finally dump all of - * the bulk descriptor references. - */ -static void osc_ptl_ev_abort(struct ptlrpc_bulk_desc *desc) -{ - ENTRY; - - LASSERT(desc->bd_brw_set != NULL); - - ptlrpc_abort_bulk(desc); - obd_brw_set_del(desc); - unmap_and_decref_bulk_desc(desc); - - 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; - struct obd_ioobj *iooptr; - void *nioptr; - __u32 xid; - ENTRY; - -restart_bulk: - 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); - body->oa.o_valid = HTON__u32(OBD_MD_FLCKSUM * CHECKSUM_BULK); - - 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 */ - - xid = ptlrpc_next_xid(); /* single xid for all pages */ - - 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) { - unmap_and_decref_bulk_desc(desc); - GOTO(out_req, 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 osc_ptl_ev_hdlr() is called by - * portals, 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_put(desc); - if (rc) { - unmap_and_decref_bulk_desc(desc); - GOTO(out_req, rc); - } - obd_brw_set_add(set, desc); - } - - request->rq_flags |= PTL_RPC_FL_NO_RESEND; - request->rq_replen = lustre_msg_size(1, size); - rc = ptlrpc_queue_wait(request); - - /* XXX bug 937 here */ - if (rc == -ETIMEDOUT && (request->rq_flags & PTL_RPC_FL_RESEND)) { - DEBUG_REQ(D_HA, request, "BULK TIMEOUT"); - ptlrpc_req_finished(request); - goto restart_bulk; - } - - if (rc) { - osc_ptl_ev_abort(desc); - GOTO(out_req, rc); - } - -#if CHECKSUM_BULK - body = lustre_msg_buf(request->rq_repmsg, 0); - if (body->oa.o_valid & NTOH__u32(OBD_MD_FLCKSUM)) { - static int cksum_counter; - __u64 server_cksum = NTOH__u64(body->oa.o_rdev); - __u64 cksum = 0; - - for (mapped = 0; mapped < page_count; mapped++) { - char *ptr = kmap(pga[mapped].pg); - int off = pga[mapped].off & (PAGE_SIZE - 1); - int len = pga[mapped].count; - - LASSERT(off + len <= PAGE_SIZE); - ost_checksum(&cksum, ptr + off, len); - kunmap(pga[mapped].pg); - } - - cksum_counter++; - if (server_cksum != cksum) { - CERROR("Bad checksum: server "LPX64", client "LPX64 - ", server NID "LPX64"\n", server_cksum, cksum, - imp->imp_connection->c_peer.peer_nid); - cksum_counter = 0; - } else if ((cksum_counter & (-cksum_counter)) == cksum_counter) - CERROR("Checksum %u from "LPX64" OK: "LPX64"\n", - cksum_counter, - imp->imp_connection->c_peer.peer_nid, cksum); - } else { - static int cksum_missed; - cksum_missed++; - if ((cksum_missed & (-cksum_missed)) == cksum_missed) - CERROR("Request checksum %u from "LPX64", no reply\n", - cksum_missed, - imp->imp_connection->c_peer.peer_nid); - } -#endif - - EXIT; - out_req: - ptlrpc_req_finished(request); - return rc; -} - -static int osc_brw_write(struct lustre_handle *conn, struct lov_stripe_md *lsm, - obd_count page_count, struct brw_page *pga, - struct obd_brw_set *set, struct obd_trans_info *oti) -{ - 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; - struct obd_ioobj *iooptr; - void *nioptr; - __u32 xid; -#if CHECKSUM_BULK - __u64 cksum = 0; -#endif - ENTRY; - -restart_bulk: - size[1] = sizeof(struct obd_ioobj); - size[2] = page_count * sizeof(struct niobuf_remote); - - request = ptlrpc_prep_req(imp, 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, lsm, page_count); - /* end almost identical to brw_read case */ - - xid = ptlrpc_next_xid(); /* single xid for all pages */ - - 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) { - unmap_and_decref_bulk_desc(desc); - GOTO(out_req, 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 = pga[mapped].count; - ost_pack_niobuf(&nioptr, pga[mapped].off, pga[mapped].count, - pga[mapped].flag, bulk->bp_xid); - ost_checksum(&cksum, bulk->bp_buf, bulk->bp_buflen); - } - -#if CHECKSUM_BULK - body->oa.o_rdev = HTON__u64(cksum); - body->oa.o_valid |= HTON__u32(OBD_MD_FLCKSUM); -#endif - /* - * 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_WRITE_BULK)) { - CERROR("obd_fail_loc=%x, skipping register_bulk\n", - OBD_FAIL_OSC_BRW_WRITE_BULK); - } else { - rc = ptlrpc_register_bulk_get(desc); - if (rc) { - unmap_and_decref_bulk_desc(desc); - GOTO(out_req, rc); - } - obd_brw_set_add(set, desc); - } - - request->rq_flags |= PTL_RPC_FL_NO_RESEND; - request->rq_replen = lustre_msg_size(1, size); - rc = ptlrpc_queue_wait(request); - - /* XXX bug 937 here */ - if (rc == -ETIMEDOUT && (request->rq_flags & PTL_RPC_FL_RESEND)) { - DEBUG_REQ(D_HA, request, "BULK TIMEOUT"); - ptlrpc_req_finished(request); - goto restart_bulk; - } - - if (rc) { - osc_ptl_ev_abort(desc); - GOTO(out_req, rc); - } - - EXIT; - out_req: - ptlrpc_req_finished(request); - return rc; -} - -#ifndef min_t -#define min_t(a,b,c) ( b OSC_BRW_MAX_IOV) - pages_per_brw = OSC_BRW_MAX_IOV; - else - pages_per_brw = page_count; - - if (cmd & OBD_BRW_WRITE) - rc = osc_brw_write(conn, md, pages_per_brw, pga, - set, oti); - 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); -} - -#ifdef __KERNEL__ -/* Note: caller will lock/unlock, and set uptodate on the pages */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -static int sanosc_brw_read(struct lustre_handle *conn, - struct lov_stripe_md *md, - obd_count page_count, - struct brw_page *pga, - struct obd_brw_set *set) -{ - struct ptlrpc_request *request = NULL; - struct ost_body *body; - struct niobuf_remote *remote, *nio_rep; - int rc, j, size[3] = {sizeof(*body)}, mapped = 0; - struct obd_ioobj *iooptr; - void *nioptr; - ENTRY; - - size[1] = sizeof(struct obd_ioobj); - size[2] = page_count * sizeof(*remote); - - request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_SAN_READ, 3, - size, NULL); - if (!request) - RETURN(-ENOMEM); - - body = lustre_msg_buf(request->rq_reqmsg, 0); - iooptr = lustre_msg_buf(request->rq_reqmsg, 1); - nioptr = lustre_msg_buf(request->rq_reqmsg, 2); - ost_pack_ioo(&iooptr, md, page_count); - - obd_kmap_get(page_count, 0); - - for (mapped = 0; mapped < page_count; mapped++) { - LASSERT(PageLocked(pga[mapped].pg)); - - kmap(pga[mapped].pg); - 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++) { - ost_unpack_niobuf(&nioptr, &remote); - } - - nioptr = lustre_msg_buf(request->rq_repmsg, 1); - nio_rep = (struct niobuf_remote*)nioptr; - - /* actual read */ - for (j = 0; j < page_count; j++) { - struct page *page = pga[j].pg; - struct buffer_head *bh; - kdev_t dev; - - /* got san device associated */ - LASSERT(class_conn2obd(conn)); - dev = class_conn2obd(conn)->u.cli.cl_sandev; - - /* hole */ - if (!nio_rep[j].offset) { - CDEBUG(D_PAGE, "hole at ino %lu; index %ld\n", - page->mapping->host->i_ino, - page->index); - memset(page_address(page), 0, PAGE_SIZE); - continue; - } - - if (!page->buffers) { - create_empty_buffers(page, dev, PAGE_SIZE); - bh = page->buffers; - - clear_bit(BH_New, &bh->b_state); - set_bit(BH_Mapped, &bh->b_state); - bh->b_blocknr = (unsigned long)nio_rep[j].offset; - - clear_bit(BH_Uptodate, &bh->b_state); - - ll_rw_block(READ, 1, &bh); - } else { - bh = page->buffers; - - /* if buffer already existed, it must be the - * one we mapped before, check it */ - LASSERT(!test_bit(BH_New, &bh->b_state)); - LASSERT(test_bit(BH_Mapped, &bh->b_state)); - LASSERT(bh->b_blocknr == - (unsigned long)nio_rep[j].offset); - - /* wait it's io completion */ - if (test_bit(BH_Lock, &bh->b_state)) - wait_on_buffer(bh); - - if (!test_bit(BH_Uptodate, &bh->b_state)) - ll_rw_block(READ, 1, &bh); - } - - - /* must do syncronous write here */ - wait_on_buffer(bh); - if (!buffer_uptodate(bh)) { - /* I/O error */ - rc = -EIO; - goto out_unmap; - } - } - -out_req: - ptlrpc_req_finished(request); - RETURN(rc); - -out_unmap: - /* Clean up on error. */ - while (mapped-- > 0) - kunmap(pga[mapped].pg); - - obd_kmap_put(page_count); - - goto out_req; -} - -static int sanosc_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_request *request = NULL; - struct ost_body *body; - struct niobuf_remote *remote, *nio_rep; - int rc, j, size[3] = {sizeof(*body)}, mapped = 0; - struct obd_ioobj *iooptr; - void *nioptr; - ENTRY; - - size[1] = sizeof(struct obd_ioobj); - size[2] = page_count * sizeof(*remote); - - request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_SAN_WRITE, - 3, size, NULL); - if (!request) - RETURN(-ENOMEM); - - body = lustre_msg_buf(request->rq_reqmsg, 0); - iooptr = lustre_msg_buf(request->rq_reqmsg, 1); - nioptr = lustre_msg_buf(request->rq_reqmsg, 2); - ost_pack_ioo(&iooptr, md, page_count); - - /* map pages, and pack request */ - obd_kmap_get(page_count, 0); - for (mapped = 0; mapped < page_count; mapped++) { - LASSERT(PageLocked(pga[mapped].pg)); - - kmap(pga[mapped].pg); - 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++) { - ost_unpack_niobuf(&nioptr, &remote); - } - - nioptr = lustre_msg_buf(request->rq_repmsg, 1); - nio_rep = (struct niobuf_remote*)nioptr; - - /* actual write */ - for (j = 0; j < page_count; j++) { - struct page *page = pga[j].pg; - struct buffer_head *bh; - kdev_t dev; - - /* got san device associated */ - LASSERT(class_conn2obd(conn)); - dev = class_conn2obd(conn)->u.cli.cl_sandev; - - if (!page->buffers) { - create_empty_buffers(page, dev, PAGE_SIZE); - } else { - /* checking */ - LASSERT(!test_bit(BH_New, &page->buffers->b_state)); - LASSERT(test_bit(BH_Mapped, &page->buffers->b_state)); - LASSERT(page->buffers->b_blocknr == - (unsigned long)nio_rep[j].offset); - } - bh = page->buffers; - - LASSERT(bh); - - /* if buffer locked, wait it's io completion */ - if (test_bit(BH_Lock, &bh->b_state)) - wait_on_buffer(bh); - - clear_bit(BH_New, &bh->b_state); - set_bit(BH_Mapped, &bh->b_state); - - /* override the block nr */ - bh->b_blocknr = (unsigned long)nio_rep[j].offset; - - /* we are about to write it, so set it - * uptodate/dirty - * page lock should garentee no race condition here */ - set_bit(BH_Uptodate, &bh->b_state); - set_bit(BH_Dirty, &bh->b_state); - - ll_rw_block(WRITE, 1, &bh); - - /* must do syncronous write here */ - wait_on_buffer(bh); - if (!buffer_uptodate(bh) || test_bit(BH_Dirty, &bh->b_state)) { - /* I/O error */ - rc = -EIO; - goto out_unmap; - } - } - -out_req: - ptlrpc_req_finished(request); - RETURN(rc); - -out_unmap: - /* Clean up on error. */ - while (mapped-- > 0) - kunmap(pga[mapped].pg); - - obd_kmap_put(page_count); - - goto out_req; -} -#else -static int sanosc_brw_read(struct lustre_handle *conn, - struct lov_stripe_md *md, - obd_count page_count, - struct brw_page *pga, - struct obd_brw_set *set) -{ - LBUG(); - return 0; -} - -static int sanosc_brw_write(struct lustre_handle *conn, - struct lov_stripe_md *md, - obd_count page_count, - struct brw_page *pga, - struct obd_brw_set *set) -{ - LBUG(); - return 0; -} -#endif - -static int sanosc_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, - struct obd_trans_info *oti) -{ - ENTRY; - - while (page_count) { - obd_count pages_per_brw; - int rc; - - if (page_count > OSC_BRW_MAX_IOV) - pages_per_brw = OSC_BRW_MAX_IOV; - else - pages_per_brw = page_count; - - if (cmd & OBD_BRW_WRITE) - rc = sanosc_brw_write(conn, md, pages_per_brw, - pga, set); - else - rc = sanosc_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); -} -#endif - -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) -{ - struct ldlm_res_id res_id = { .name = {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, 0, &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, 0, &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, NULL, - 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); - struct ldlm_res_id res_id = { .name = {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; -} - -/* Retrieve object striping information. - * - * @lmmu is a pointer to an in-core 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 (we only use 1 slot here). - */ -static int osc_getstripe(struct lustre_handle *conn, struct lov_stripe_md *lsm, - struct lov_mds_md *lmmu) -{ - struct lov_mds_md lmm, *lmmk; - int rc, lmm_size; - ENTRY; - - 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 (lmm.lmm_ost_count < 1) - RETURN(-EOVERFLOW); - - lmm_size = sizeof(lmm) + sizeof(lmm.lmm_objects[0]); - OBD_ALLOC(lmmk, lmm_size); - if (rc < 0) - RETURN(rc); - - lmmk->lmm_stripe_count = 1; - lmmk->lmm_ost_count = 1; - lmmk->lmm_object_id = lsm->lsm_object_id; - lmmk->lmm_objects[0].l_object_id = lsm->lsm_object_id; - - if (copy_to_user(lmmu, lmmk, lmm_size)) - rc = -EFAULT; - - OBD_FREE(lmmk, lmm_size); - - 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) { -#if 0 - 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); - } -#endif - 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; - struct obd_uuid uuid; - - 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(uuid)) { - 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(uuid)); - - memcpy(data->ioc_inlbuf2, &obddev->obd_uuid, sizeof(uuid)); - - err = copy_to_user((void *)uarg, buf, len); - if (err) - err = -EFAULT; - OBD_FREE(buf, len); - GOTO(out, err); - } - case LL_IOC_LOV_SETSTRIPE: - err = obd_alloc_memmd(conn, karg); - if (err > 0) - err = 0; - GOTO(out, err); - case LL_IOC_LOV_GETSTRIPE: - err = osc_getstripe(conn, karg, uarg); - GOTO(out, err); - default: - CERROR ("osc_ioctl(): unrecognised ioctl %#x\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; - - LASSERT(imp->imp_obd); - - 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 = { 0 }; - 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 = - (char *)&imp->imp_obd->u.cli.cl_target_uuid; - ioc_data.ioc_offset = active; - rc = obd_iocontrol(IOC_LOV_SET_OSC_ACTIVE, &fakeconn, - sizeof ioc_data, &ioc_data, NULL); - if (rc) - CERROR("error disabling %s on LOV %p/%s: %d\n", - imp->imp_obd->u.cli.cl_target_uuid.uuid, - notify_obd, notify_obd->obd_uuid.uuid, rc); - } else { - CDEBUG(D_HA, "No exports for obd %p/%s, can't notify about " - "%p\n", notify_obd, notify_obd->obd_uuid.uuid, - imp->imp_obd->obd_uuid.uuid); - } -} - -static int osc_recover(struct obd_import *imp, int phase) -{ - int rc; - unsigned long flags; - int msg_flags; - struct ptlrpc_request *req; - struct ldlm_namespace *ns = imp->imp_obd->obd_namespace; - ENTRY; - - CDEBUG(D_HA, "%s: entering phase: %d\n", - imp->imp_obd->obd_name, phase); - switch(phase) { - - case PTLRPC_RECOVD_PHASE_PREPARE: { - if (imp->imp_flags & IMP_REPLAYABLE) { - CDEBUG(D_HA, "failover OST\n"); - /* If we're a failover OSC/OST, just cancel unused - * locks to simplify lock replay. - */ - ldlm_cli_cancel_unused(ns, NULL, LDLM_FL_LOCAL_ONLY); - } else { - CDEBUG(D_HA, "non-failover OST\n"); - /* Non-failover OSTs (LLNL scenario) disable the OSC - * and invalidate local state. - */ - ldlm_namespace_cleanup(ns, 1 /* no network ops */); - ptlrpc_abort_inflight(imp, 0); - set_osc_active(imp, 0 /* inactive */); - } - RETURN(0); - } - - case PTLRPC_RECOVD_PHASE_RECOVER: { - reconnect: - imp->imp_flags &= ~IMP_INVALID; - rc = ptlrpc_reconnect_import(imp, OST_CONNECT, &req); - - msg_flags = req->rq_repmsg - ? lustre_msg_get_op_flags(req->rq_repmsg) - : 0; - - if (rc == -EBUSY && (msg_flags & MSG_CONNECT_RECOVERING)) - CERROR("reconnect denied by recovery; should retry\n"); - - if (rc) { - if (phase != PTLRPC_RECOVD_PHASE_NOTCONN) { - CERROR("can't reconnect, invalidating\n"); - ldlm_namespace_cleanup(ns, 1); - ptlrpc_abort_inflight(imp, 0); - } - imp->imp_flags |= IMP_INVALID; - ptlrpc_req_finished(req); - RETURN(rc); - } - - if (msg_flags & MSG_CONNECT_RECOVERING) { - /* Replay if they want it. */ - DEBUG_REQ(D_HA, req, "OST wants replay"); - rc = ptlrpc_replay(imp); - if (rc) - GOTO(check_rc, rc); - - rc = ldlm_replay_locks(imp); - if (rc) - GOTO(check_rc, rc); - - rc = signal_completed_replay(imp); - if (rc) - GOTO(check_rc, rc); - } else if (msg_flags & MSG_CONNECT_RECONNECT) { - DEBUG_REQ(D_HA, req, "reconnecting to MDS\n"); - /* Nothing else to do here. */ - } else { - DEBUG_REQ(D_HA, req, "evicted: invalidating\n"); - /* Otherwise, clean everything up. */ - ldlm_namespace_cleanup(ns, 1); - ptlrpc_abort_inflight(imp, 0); - } - - ptlrpc_req_finished(req); - - spin_lock_irqsave(&imp->imp_lock, flags); - imp->imp_level = LUSTRE_CONN_FULL; - imp->imp_flags &= ~IMP_INVALID; - spin_unlock_irqrestore(&imp->imp_lock, flags); - - /* Is this the right place? Should we do this in _PREPARE - * as well? What about raising the level right away? - */ - ptlrpc_wake_delayed(imp); - - rc = ptlrpc_resend(imp); - if (rc) - GOTO(check_rc, rc); - - set_osc_active(imp, 1 /* active */); - RETURN(0); - - check_rc: - /* If we get disconnected in the middle, recovery has probably - * failed. Reconnect and find out. - */ - if (rc == -ENOTCONN) - goto reconnect; - RETURN(rc); - } - case PTLRPC_RECOVD_PHASE_NOTCONN: - osc_recover(imp, PTLRPC_RECOVD_PHASE_PREPARE); - RETURN(osc_recover(imp, PTLRPC_RECOVD_PHASE_RECOVER)); - - default: - RETURN(-EINVAL); - } -} - -static int osc_connect(struct lustre_handle *conn, struct obd_device *obd, - struct obd_uuid *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_owner: THIS_MODULE, - 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 -}; - -struct obd_ops sanosc_obd_ops = { - o_owner: THIS_MODULE, - o_attach: osc_attach, - o_detach: osc_detach, - 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, -#ifdef __KERNEL__ - o_setup: client_sanobd_setup, - o_brw: sanosc_brw, -#endif - o_punch: osc_punch, - o_enqueue: osc_enqueue, - o_cancel: osc_cancel, - o_cancel_unused: osc_cancel_unused, - o_iocontrol: osc_iocontrol, -}; - -int __init osc_init(void) -{ - struct lprocfs_static_vars lvars; - int rc; - ENTRY; - - LASSERT(sizeof(struct osc_obdo_data) <= FD_OSTDATA_SIZE); - - lprocfs_init_vars(&lvars); - - rc = class_register_type(&osc_obd_ops, lvars.module_vars, - LUSTRE_OSC_NAME); - if (rc) - RETURN(rc); - - rc = class_register_type(&sanosc_obd_ops, lvars.module_vars, - LUSTRE_SANOSC_NAME); - if (rc) - class_unregister_type(LUSTRE_OSC_NAME); - - RETURN(rc); -} - -static void __exit osc_exit(void) -{ - class_unregister_type(LUSTRE_SANOSC_NAME); - class_unregister_type(LUSTRE_OSC_NAME); -} - -#ifdef __KERNEL__ -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Object Storage Client (OSC)"); -MODULE_LICENSE("GPL"); - -module_init(osc_init); -module_exit(osc_exit); -#endif 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 c158a0f..0000000 --- a/lustre/ost/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 = ost -modulefs_DATA = ost.o -EXTRA_PROGRAMS = ost - -LINX=obd_pack.c target.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 c44093c..0000000 --- a/lustre/ost/lproc_ost.c +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#define DEBUG_SUBSYSTEM S_OST - -#include -#include - -#ifndef LPROCFS -struct lprocfs_vars lprocfs_obd_vars[] = { {0} }; -struct lprocfs_vars lprocfs_module_vars[] = { {0} }; -#else -struct lprocfs_vars lprocfs_obd_vars[] = { - { "uuid", lprocfs_rd_uuid, 0, 0 }, - { 0 } -}; - -struct lprocfs_vars lprocfs_module_vars[] = { - { "num_refs", lprocfs_rd_numrefs, 0, 0 }, - { 0 } -}; - -#endif /* LPROCFS */ -LPROCFS_INIT_VARS(lprocfs_module_vars, lprocfs_obd_vars) diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c deleted file mode 100644 index 18a1b85..0000000 --- a/lustre/ost/ost_handler.c +++ /dev/null @@ -1,921 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2001-2003 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 -#include - -inline void oti_to_request(struct obd_trans_info *oti, struct ptlrpc_request *req) -{ - if (oti && req->rq_repmsg) - req->rq_repmsg->transno = HTON__u64(oti->oti_transno); - EXIT; -} - -static int ost_destroy(struct ptlrpc_request *req, struct obd_trans_info *oti) -{ - 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, oti); - 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_syncfs(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(0, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - RETURN(rc); - - rc = obd_syncfs(conn); - if (rc) { - CERROR("ost: syncfs failed: rc %d\n", rc); - req->rq_status = rc; - RETURN(rc); - } - - RETURN(0); -} - -static int ost_open(struct ptlrpc_request *req, struct obd_trans_info *oti) -{ - 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, oti); - RETURN(0); -} - -static int ost_close(struct ptlrpc_request *req, struct obd_trans_info *oti) -{ - 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, oti); - RETURN(0); -} - -static int ost_create(struct ptlrpc_request *req, struct obd_trans_info *oti) -{ - 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, oti); - RETURN(0); -} - -static int ost_punch(struct ptlrpc_request *req, struct obd_trans_info *oti) -{ - 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, oti); - RETURN(0); -} - -static int ost_setattr(struct ptlrpc_request *req, struct obd_trans_info *oti) -{ - 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, oti); - RETURN(0); -} - -static int ost_bulk_timeout(void *data) -{ - ENTRY; - /* We don't fail the connection here, because having the export - * killed makes the (vital) call to commitrw very sad. - */ - 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; - struct obd_ioobj *tmp1; - void *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 cmd, i, j, objcount, niocount, size = sizeof(*body); - int rc = 0; -#if CHECKSUM_BULK - __u64 cksum = 0; -#endif - 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, req->rq_status = -EIO); - - /* Hmm, we don't return anything in this reply buffer? - * We should be returning per-page status codes and also - * per-object size, blocks count, mtime, ctime. (bug 593) */ - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc) - GOTO(out, req->rq_status = rc); - - 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++) { - /* XXX verify niobuf[j].offset > niobuf[j-1].offset */ - 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, NULL); - - if (req->rq_status) - GOTO(out, req->rq_status); - - desc = ptlrpc_prep_bulk(req->rq_connection); - if (desc == NULL) - GOTO(out_local, rc = -ENOMEM); - desc->bd_ptl_ev_hdlr = NULL; - 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; - if (body->oa.o_valid & NTOH__u32(OBD_MD_FLCKSUM)) - ost_checksum(&cksum, bulk->bp_buf, bulk->bp_buflen); - } - - rc = ptlrpc_bulk_put(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, NULL); - -out_bulk: - ptlrpc_bulk_decref(desc); -out_local: - OBD_FREE(local_nb, sizeof(*local_nb) * niocount); -out: - if (rc) - ptlrpc_error(req->rq_svc, req); - else { -#if CHECKSUM_BULK - body = lustre_msg_buf(req->rq_repmsg, 0); - body->oa.o_rdev = HTON__u64(cksum); - body->oa.o_valid |= HTON__u32(OBD_MD_FLCKSUM); -#endif - ptlrpc_reply(req->rq_svc, req); - } - - RETURN(rc); -} - -static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - struct ptlrpc_bulk_desc *desc; - struct obd_ioobj *tmp1; - void *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 cmd, i, j, objcount, niocount, size = sizeof(*body); - int rc = 0; - 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; - - if (OBD_FAIL_CHECK(OBD_FAIL_OST_BRW_WRITE_BULK)) - GOTO(out, req->rq_status = -EIO); - - 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++) { - /* XXX verify niobuf[j].offset > niobuf[j-1].offset */ - 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, oti); - - if (req->rq_status) - GOTO(out_local, rc = 0); - - desc = ptlrpc_prep_bulk(req->rq_connection); - if (desc == NULL) - GOTO(out_local, rc = -ENOMEM); - desc->bd_ptl_ev_hdlr = NULL; - desc->bd_portal = OSC_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_bulk_get(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_RCVD, - &lwi); - if (rc) { - LASSERT(rc == -ETIMEDOUT); - ptlrpc_abort_bulk(desc); - recovd_conn_fail(desc->bd_connection); - obd_commitrw(cmd, conn, objcount, ioo, niocount, local_nb, - desc_priv, oti); - GOTO(out_bulk, rc); - } - -#if CHECKSUM_BULK - if ((body->oa.o_valid & NTOH__u32(OBD_MD_FLCKSUM))) { - static int cksum_counter; - __u64 client_cksum = NTOH__u64(body->oa.o_rdev); - __u64 cksum = 0; - - for (i = 0; i < niocount; i++) { - char *ptr = kmap(local_nb[i].page); - int off = local_nb[i].offset & (PAGE_SIZE - 1); - int len = local_nb[i].len; - - LASSERT(off + len <= PAGE_SIZE); - ost_checksum(&cksum, ptr + off, len); - kunmap(local_nb[i].page); - } - - if (client_cksum != cksum) { - CERROR("Bad checksum: client "LPX64", server "LPX64 - ", client NID "LPX64"\n", client_cksum, cksum, - req->rq_connection->c_peer.peer_nid); - cksum_counter = 1; - } else { - cksum_counter++; - if ((cksum_counter & (-cksum_counter)) == cksum_counter) - CERROR("Checksum %d from "LPX64": "LPX64" OK\n", - cksum_counter, - req->rq_connection->c_peer.peer_nid, - cksum); - } - } -#endif - - req->rq_status = obd_commitrw(cmd, conn, objcount, ioo, niocount, - local_nb, desc_priv, oti); - - out_bulk: - ptlrpc_bulk_decref(desc); - out_local: - OBD_FREE(local_nb, sizeof(*local_nb) * niocount); - out: - if (!rc) - /* Hmm, we don't return anything in this reply buffer? - * We should be returning per-page status codes and also - * per-object size, blocks count, mtime, ctime. (bug 593) */ - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, - &req->rq_repmsg); - if (rc) - ptlrpc_error(req->rq_svc, req); - else { - oti_to_request(oti, req); - rc = ptlrpc_reply(req->rq_svc, req); - } - RETURN(rc); -} - -static int ost_san_brw(struct ptlrpc_request *req, int alloc) -{ - struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; - struct niobuf_remote *remote_nb, *res_nb; - struct obd_ioobj *ioo; - struct ost_body *body; - int cmd, rc, i, j, objcount, niocount, size[2] = {sizeof(*body)}; - void *tmp1, *tmp2, *end2; - 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 = alloc ? OBD_BRW_WRITE : OBD_BRW_READ; - - 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); - - /* 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_san_preprw(cmd, conn, objcount, tmp1, - niocount, tmp2); - - if (req->rq_status) { - rc = 0; - goto out; - } - - remote_nb = lustre_msg_buf(req->rq_repmsg, 1); - res_nb = lustre_msg_buf(req->rq_reqmsg, 2); - for (i = 0; i < niocount; i++) { - /* this advances remote_nb */ - ost_pack_niobuf((void **)&remote_nb, - res_nb[i].offset, - res_nb[i].len, /* 0 */ - res_nb[i].flags, /* 0 */ - res_nb[i].xid - ); - } - - rc = 0; - -out: - 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; -} - -static int filter_recovery_request(struct ptlrpc_request *req, - struct obd_device *obd, int *process) -{ - switch (req->rq_reqmsg->opc) { - case OST_CONNECT: /* This will never get here, but for completeness. */ - case OST_DISCONNECT: - *process = 1; - RETURN(0); - - case OST_CLOSE: - case OST_CREATE: - case OST_DESTROY: - case OST_OPEN: - case OST_PUNCH: - case OST_SETATTR: - case OST_SYNCFS: - case OST_WRITE: - case LDLM_ENQUEUE: - *process = target_queue_recovery_request(req, obd); - RETURN(0); - - default: - DEBUG_REQ(D_ERROR, req, "not permitted during recovery"); - *process = 0; - /* XXX what should we set rq_status to here? */ - RETURN(ptlrpc_error(req->rq_svc, req)); - } -} - -static int ost_handle(struct ptlrpc_request *req) -{ - struct obd_trans_info trans_info = { 0, }, *oti = &trans_info; - int should_process, 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) { - struct obd_device *obd; - - if (req->rq_export == NULL) { - CERROR("lustre_ost: operation %d on unconnected OST\n", - req->rq_reqmsg->opc); - req->rq_status = -ENOTCONN; - GOTO(out, rc = -ENOTCONN); - } - - obd = req->rq_export->exp_obd; - - spin_lock_bh(&obd->obd_processing_task_lock); - if (obd->obd_flags & OBD_ABORT_RECOVERY) - target_abort_recovery(obd); - spin_unlock_bh(&obd->obd_processing_task_lock); - - if (obd->obd_flags & OBD_RECOVERING) { - rc = filter_recovery_request(req, obd, &should_process); - if (rc || !should_process) - RETURN(rc); - } else if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) { -#if 0 -/* need to store this reply somewhere... */ - if (req->rq_xid == med->med_last_xid) { - DEBUG_REQ(D_HA, req, "resending reply"); - OBD_ALLOC(req->rq_repmsg, med->med_last_replen); - req->rq_replen = med->med_last_replen; - memcpy(req->rq_repmsg, med->med_last_reply, - req->rq_replen); - ptlrpc_reply(req->rq_svc, req); - return 0; - } - DEBUG_REQ(D_HA, req, "no reply for resend, continuing"); -#endif - } - - } - - 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, ost_handle); - 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, oti); - break; - case OST_DESTROY: - CDEBUG(D_INODE, "destroy\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_DESTROY_NET, 0); - rc = ost_destroy(req, oti); - 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, oti); - break; - case OST_OPEN: - CDEBUG(D_INODE, "open\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_OPEN_NET, 0); - rc = ost_open(req, oti); - break; - case OST_CLOSE: - CDEBUG(D_INODE, "close\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_CLOSE_NET, 0); - rc = ost_close(req, oti); - break; - case OST_WRITE: - CDEBUG(D_INODE, "write\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_BRW_NET, 0); - rc = ost_brw_write(req, oti); - /* 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_SAN_READ: - CDEBUG(D_INODE, "san read\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_BRW_NET, 0); - rc = ost_san_brw(req, 0); - /* ost_san_brw sends its own replies */ - RETURN(rc); - case OST_SAN_WRITE: - CDEBUG(D_INODE, "san write\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_BRW_NET, 0); - rc = ost_san_brw(req, 1); - /* ost_san_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, oti); - break; - case OST_STATFS: - CDEBUG(D_INODE, "statfs\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_STATFS_NET, 0); - rc = ost_statfs(req); - break; - case OST_SYNCFS: - CDEBUG(D_INODE, "sync\n"); - OBD_FAIL_RETURN(OBD_FAIL_OST_SYNCFS_NET, 0); - rc = ost_syncfs(req); - break; - case LDLM_ENQUEUE: - CDEBUG(D_INODE, "enqueue\n"); - OBD_FAIL_RETURN(OBD_FAIL_LDLM_ENQUEUE, 0); - rc = ldlm_handle_enqueue(req, ldlm_server_completion_ast, - ldlm_server_blocking_ast); - 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; - /* If we're DISCONNECTing, the export_data is already freed */ - if (!rc && req->rq_reqmsg->opc != OST_DISCONNECT) { - struct obd_device *obd = req->rq_export->exp_obd; - if ((obd->obd_flags & OBD_NO_TRANSNO) == 0) { - req->rq_repmsg->last_committed = - HTON__u64(obd->obd_last_committed); - } else { - DEBUG_REQ(D_IOCTL, req, - "not sending last_committed update"); - } - CDEBUG(D_INFO, "last_committed "LPU64", xid "LPX64"\n", - obd->obd_last_committed, HTON__u64(req->rq_xid)); - } - -out: - if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_LAST_REPLAY) { - struct obd_device *obd = req->rq_export->exp_obd; - - if (obd && (obd->obd_flags & OBD_RECOVERING)) { - DEBUG_REQ(D_HA, req, "LAST_REPLAY, queuing reply"); - return target_queue_final_reply(req, rc); - } - /* Lost a race with recovery; let the error path DTRT. */ - rc = req->rq_status = -ENOTCONN; - } - - 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); - else - oti_to_request(oti, req); - ptlrpc_reply(req->rq_svc, req); - } - - return 0; -} - -static int ost_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - struct ost_obd *ost = &obddev->u.ost; - int err; - int i; - ENTRY; - - ost->ost_service = ptlrpc_init_svc(OST_NEVENTS, OST_NBUFS, - OST_BUFSIZE, OST_MAXREQSIZE, - OST_REQUEST_PORTAL, OSC_REPLY_PORTAL, - ost_handle, "ost"); - if (!ost->ost_service) { - CERROR("failed to start service\n"); - GOTO(error_disc, err = -ENOMEM); - } - - 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: - RETURN(err); -} - -static int ost_cleanup(struct obd_device * obddev) -{ - struct ost_obd *ost = &obddev->u.ost; - int err = 0; - - ENTRY; - - ptlrpc_stop_all_threads(ost->ost_service); - ptlrpc_unregister_service(ost->ost_service); - - RETURN(err); -} - -int ost_attach(struct obd_device *dev, obd_count len, void *data) -{ - struct lprocfs_static_vars lvars; - - lprocfs_init_vars(&lvars); - return lprocfs_obd_attach(dev, lvars.obd_vars); -} - -int ost_detach(struct obd_device *dev) -{ - return lprocfs_obd_detach(dev); -} - -/* I don't think this function is ever used, since nothing - * connects directly to this module. - */ -static int ost_connect(struct lustre_handle *conn, - struct obd_device *obd, struct obd_uuid *cluuid, - struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct obd_export *exp; - int rc; - ENTRY; - - if (!conn || !obd || !cluuid) - RETURN(-EINVAL); - - rc = class_connect(conn, obd, cluuid); - if (rc) - RETURN(rc); - exp = class_conn2export(conn); - LASSERT(exp); - - RETURN(0); -} - -/* use obd ops to offer management infrastructure */ -static struct obd_ops ost_obd_ops = { - o_owner: THIS_MODULE, - o_attach: ost_attach, - o_detach: ost_detach, - o_setup: ost_setup, - o_cleanup: ost_cleanup, - o_connect: ost_connect, -}; - -static int __init ost_init(void) -{ - struct lprocfs_static_vars lvars; - ENTRY; - - lprocfs_init_vars(&lvars); - RETURN(class_register_type(&ost_obd_ops, lvars.module_vars, - LUSTRE_OST_NAME)); -} - -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/ptlbd/.cvsignore b/lustre/ptlbd/.cvsignore deleted file mode 100644 index e995588..0000000 --- a/lustre/ptlbd/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.deps -Makefile -Makefile.in diff --git a/lustre/ptlbd/Makefile.am b/lustre/ptlbd/Makefile.am deleted file mode 100644 index bfaeb25..0000000 --- a/lustre/ptlbd/Makefile.am +++ /dev/null @@ -1,14 +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 = ptlbd -modulefs_DATA = ptlbd.o -EXTRA_PROGRAMS = ptlbd - -ptlbd_SOURCES = blk.c client.c main.c rpc.c server.c - -include $(top_srcdir)/Rules diff --git a/lustre/ptlbd/blk.c b/lustre/ptlbd/blk.c deleted file mode 100644 index 70ea9e4..0000000 --- a/lustre/ptlbd/blk.c +++ /dev/null @@ -1,257 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * Author: Zach Brown - * - * 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_PTLBD - -#include -#include -#include -#include -#include - -/* - * todo: - * assign proper major number - * allow more minors - * discover actual block sizes? - * allow more than one sector per io - * think about vary-io - * restrict single ops to sequential block io - * ddn target addresses need to be 32 bit - * cant get to addresses after 0xFFFF0000 - */ - -#define PTLBD_MAJOR 253 -#define PTLBD_MAX_MINOR 1 - -#define MAJOR_NR PTLBD_MAJOR -#define LOCAL_END_REQUEST -#include -#include -#include -#include - -static int ptlbd_size_size[PTLBD_MAX_MINOR]; -static int ptlbd_size[PTLBD_MAX_MINOR]; -static int ptlbd_hardsect_size[PTLBD_MAX_MINOR]; -static int ptlbd_max_sectors[PTLBD_MAX_MINOR]; -//RHism static char ptlbd_dev_varyio[PTLBD_MAX_MINOR]; - -/* - * per minor state, indexed by minor. - */ - -static struct ptlbd_obd *one_for_now; - -void ptlbd_blk_register(struct ptlbd_obd *ptlbd) -{ - ENTRY; - one_for_now = ptlbd; - EXIT; -} - -static struct ptlbd_obd * ptlbd_get_minor(int minor) -{ - ENTRY; - if ( minor >= PTLBD_MAX_MINOR ) - RETURN( ERR_PTR(-ENODEV) ); - RETURN(one_for_now); -} - -static struct ptlbd_obd * ptlbd_get_inode(struct inode *inode) -{ - ENTRY; - - if ( inode == NULL ) /* can this really happen? */ - RETURN( ERR_PTR(-EINVAL) ); - - return ptlbd_get_minor(MINOR(inode->i_rdev)); -} - -static int ptlbd_open(struct inode *inode, struct file *file) -{ - struct ptlbd_obd *ptlbd = ptlbd_get_inode(inode); - ENTRY; - - if ( IS_ERR(ptlbd) ) - RETURN(PTR_ERR(ptlbd)); - if ( ptlbd->bd_import.imp_connection == NULL ) - RETURN(-ENODEV); - - ptlbd->refcount++; - RETURN(0); -} - -static int ptlbd_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct ptlbd_obd *ptlbd; - int ret; - - if ( ! capable(CAP_SYS_ADMIN) ) - RETURN(-EPERM); - - ptlbd = ptlbd_get_inode(inode); - if ( IS_ERR(ptlbd) ) - RETURN( PTR_ERR(ptlbd) ); - - switch(cmd) { - case BLKFLSBUF: - ret = blk_ioctl(inode->i_rdev, cmd, arg); - break; - default: - ret = -EINVAL; - break; - } - - RETURN(ret); -} - -static int ptlbd_release(struct inode *inode, struct file *file) -{ - struct ptlbd_obd *ptlbd = ptlbd_get_inode(inode); - ENTRY; - - if ( IS_ERR(ptlbd) ) - RETURN( PTR_ERR(ptlbd) ); - - ptlbd->refcount--; - RETURN(0); -} - -static void ptlbd_end_request_havelock(struct request *req) -{ - struct buffer_head *bh; - int uptodate = 1; - - if ( req->errors ) - uptodate = 0; - - while( (bh = req->bh) != NULL ) { - blk_finished_io(bh->b_size >> 9); - req->bh = bh->b_reqnext; - bh->b_reqnext = NULL; - bh->b_end_io(bh, uptodate); - } - blkdev_release_request(req); -} - -#if 0 -static void ptlbd_end_request_getlock(struct request *req) -{ - unsigned long flags; - - spin_lock_irqsave(&io_request_lock, flags); - ptlbd_end_request_havelock(req); - spin_unlock_irqrestore(&io_request_lock, flags); -} -#endif - -static void ptlbd_request(request_queue_t *q) -{ - struct ptlbd_obd *ptlbd; - struct request *req; - ptlbd_cmd_t cmd; - ENTRY; - - while ( !QUEUE_EMPTY ) { - req = CURRENT; - ptlbd = ptlbd_get_minor(MINOR(req->rq_dev)); - - blkdev_dequeue_request(req); - - if ( ptlbd->refcount <= 0 ) { - req->errors++; - ptlbd_end_request_havelock(req); - return; - } - - spin_unlock_irq(&io_request_lock); - - /* XXX dunno if we're supposed to get this or not.. */ - LASSERT(req->cmd != READA); - - if ( req->cmd == READ ) - cmd = PTLBD_READ; - else - cmd = PTLBD_WRITE; - - ptlbd_send_req(ptlbd, cmd, req->bh); - - spin_lock_irq(&io_request_lock); - - ptlbd_end_request_havelock(req); - } -} - -static struct block_device_operations ptlbd_ops = { - .owner = THIS_MODULE, - .open = ptlbd_open, - .release = ptlbd_release, - .ioctl = ptlbd_ioctl, -}; - -int ptlbd_blk_init(void) -{ - int ret; - int i; - ENTRY; - - ret = register_blkdev(PTLBD_MAJOR, "ptlbd", &ptlbd_ops); - if ( ret < 0 ) - RETURN(ret); - - blk_size[PTLBD_MAJOR] = ptlbd_size; - blksize_size[PTLBD_MAJOR] = ptlbd_size_size; - hardsect_size[PTLBD_MAJOR] = ptlbd_hardsect_size; - max_sectors[PTLBD_MAJOR] = ptlbd_max_sectors; - //RHism blkdev_varyio[PTLBD_MAJOR] = ptlbd_dev_varyio; - - blk_init_queue(BLK_DEFAULT_QUEUE(PTLBD_MAJOR), ptlbd_request); - blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); - - for ( i = 0 ; i < PTLBD_MAX_MINOR ; i++) { - ptlbd_size_size[i] = 4096; - ptlbd_size[i] = (4096*2048) >> BLOCK_SIZE_BITS; - ptlbd_hardsect_size[i] = 4096; - ptlbd_max_sectors[i] = 2; - //RHism ptlbd_dev_varyio[i] = 0; - /* XXX register_disk? */ - } - - return 0; -} - -void ptlbd_blk_exit(void) -{ - int ret; - ENTRY; - blk_cleanup_queue(BLK_DEFAULT_QUEUE(PTLBD_MAJOR)); - ret = unregister_blkdev(PTLBD_MAJOR, "ptlbd"); - if ( ret ) /* XXX */ - printk("unregister_blkdev() failed: %d\n", ret); -} - -#undef MAJOR_NR diff --git a/lustre/ptlbd/client.c b/lustre/ptlbd/client.c deleted file mode 100644 index 67d0b85..0000000 --- a/lustre/ptlbd/client.c +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * Author: Zach Brown - * - * 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_PTLBD - -#include -#include -#include -#include -#include - -static int ptlbd_cl_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - struct ptlbd_obd *ptlbd = &obddev->u.ptlbd; - struct obd_import *imp = &ptlbd->bd_import; - struct obd_ioctl_data* data = buf; - struct obd_uuid server_uuid; - ENTRY; - - if ( ptlbd->bd_import.imp_connection != NULL ) - RETURN(-EALREADY); - - if (data->ioc_inllen1 < 1) { - CERROR("requires a PTLBD server UUID\n"); - RETURN(-EINVAL); - } - - if (data->ioc_inllen1 > 37) { - CERROR("PTLBD server UUID must be less than 38 characters\n"); - RETURN(-EINVAL); - } - - obd_str2uuid(&server_uuid, data->ioc_inlbuf1); - - 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); - /* - * from client_obd_connect.. *shrug* - */ - INIT_LIST_HEAD(&imp->imp_chain); - imp->imp_max_transno = 0; - imp->imp_peer_committed_transno = 0; - imp->imp_level = LUSTRE_CONN_FULL; - - ptlrpc_init_client(PTLBD_REQUEST_PORTAL, PTLBD_REPLY_PORTAL, - "ptlbd", &ptlbd->bd_client); - imp->imp_client = &ptlbd->bd_client; - imp->imp_obd = obddev; - - ptlbd_blk_register(ptlbd); - - RETURN(0); -} - -static int ptlbd_cl_cleanup(struct obd_device *obddev) -{ -// struct ptlbd_obd *ptlbd = &obddev->u.ptlbd; - ENTRY; - - CERROR("I should be cleaning things up\n"); - - RETURN(0); -} - -#if 0 -static int ptlbd_cl_connect(struct lustre_handle *conn, struct obd_device *obd, - struct obd_uuid cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct ptlbd_obd *ptlbd = &obd->u.ptlbd; - struct obd_import *imp = &ptlbd->bd_import; - int rc; - ENTRY; - - rc = class_connect(conn, obd, cluuid); - if (rc) - RETURN(rc); - - INIT_LIST_HEAD(&imp->imp_chain); - imp->imp_max_transno = 0; - imp->imp_peer_committed_transno = 0; - imp->imp_level = LUSTRE_CONN_FULL; - - RETURN(0); -} -#endif - -static struct obd_ops ptlbd_cl_obd_ops = { - o_owner: THIS_MODULE, - o_setup: ptlbd_cl_setup, - o_cleanup: ptlbd_cl_cleanup, -#if 0 - o_connect: ptlbd_cl_connect, - o_disconnect: class_disconnect -#endif -}; - -int ptlbd_cl_init(void) -{ - struct lprocfs_static_vars lvars; - - lprocfs_init_vars(&lvars); - return class_register_type(&ptlbd_cl_obd_ops, lvars.module_vars, - OBD_PTLBD_CL_DEVICENAME); -} - -void ptlbd_cl_exit(void) -{ - class_unregister_type(OBD_PTLBD_CL_DEVICENAME); -} diff --git a/lustre/ptlbd/main.c b/lustre/ptlbd/main.c deleted file mode 100644 index a95cc3f..0000000 --- a/lustre/ptlbd/main.c +++ /dev/null @@ -1,70 +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 - -#define DEBUG_SUBSYSTEM S_PTLBD - -#include -#include -#include - -#include - -static int __init ptlbd_init(void) -{ - int ret; - ENTRY; - - ret = ptlbd_cl_init(); - if ( ret < 0 ) - RETURN(ret); - - ret = ptlbd_sv_init(); - if ( ret < 0 ) - GOTO(out_cl, ret); - - ret = ptlbd_blk_init(); - if ( ret < 0 ) - GOTO(out_sv, ret); - - RETURN(0); - -out_sv: - ptlbd_sv_exit(); -out_cl: - ptlbd_cl_exit(); - RETURN(ret); -} - -static void __exit ptlbd_exit(void) -{ - ENTRY; - ptlbd_cl_exit(); - ptlbd_sv_exit(); - EXIT; -} - -module_init(ptlbd_init); -module_exit(ptlbd_exit); -MODULE_LICENSE("GPL"); diff --git a/lustre/ptlbd/rpc.c b/lustre/ptlbd/rpc.c deleted file mode 100644 index 4daee83..0000000 --- a/lustre/ptlbd/rpc.c +++ /dev/null @@ -1,252 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * Author: Zach Brown - * - * 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_PTLBD - -#include -#include -#include -#include -#include - -int ptlbd_send_req(struct ptlbd_obd *ptlbd, ptlbd_cmd_t cmd, - struct buffer_head *first_bh) -{ - struct obd_import *imp = &ptlbd->bd_import; - struct ptlbd_op *op; - struct ptlbd_niob *niob, *niobs; - struct ptlbd_rsp *rsp; - struct ptlrpc_request *req; - struct ptlrpc_bulk_desc *desc; - struct buffer_head *bh; - unsigned int page_count; - int rc, rep_size, size[2]; - __u32 xid; - ENTRY; - - LASSERT(cmd == PTLBD_READ || cmd == PTLBD_WRITE); - - for ( page_count = 0, bh = first_bh ; bh ; bh = bh->b_next ) - page_count++; - - size[0] = sizeof(struct ptlbd_op); - size[1] = page_count * sizeof(struct ptlbd_niob); - - req = ptlrpc_prep_req(imp, cmd, 2, size, NULL); - if (!req) - RETURN(-ENOMEM); - - op = lustre_msg_buf(req->rq_reqmsg, 0); - niobs = lustre_msg_buf(req->rq_reqmsg, 1); - - /* XXX pack */ - op->op_cmd = cmd; - op->op_lun = 0; - op->op_niob_cnt = page_count; - op->op__padding = 0; - op->op_block_cnt = page_count; - - desc = ptlrpc_prep_bulk(imp->imp_connection); - if ( desc == NULL ) - GOTO(out_req, rc = -ENOMEM); - desc->bd_portal = PTLBD_BULK_PORTAL; - desc->bd_ptl_ev_hdlr = NULL; - - xid = ptlrpc_next_xid(); - - for ( niob = niobs, bh = first_bh ; bh ; bh = bh->b_next, niob++ ) { - struct ptlrpc_bulk_page *bulk = ptlrpc_prep_bulk_page(desc); - if (bulk == NULL) - GOTO(out_req, rc = -ENOMEM); - - niob->n_xid = xid; - niob->n_block_nr = bh->b_blocknr; - niob->n_offset = bh_offset(bh); - niob->n_length = bh->b_size; - - bulk->bp_xid = xid; - bulk->bp_buf = bh->b_data; - bulk->bp_page = bh->b_page; - bulk->bp_buflen = bh->b_size; - } - - if ( cmd == PTLBD_READ ) - rc = ptlrpc_register_bulk_put(desc); - else - rc = ptlrpc_register_bulk_get(desc); - - if (rc) - GOTO(out_desc, rc); - - rep_size = sizeof(struct ptlbd_rsp); - req->rq_replen = lustre_msg_size(1, &rep_size); - - /* XXX find out how we're really supposed to manage levels */ - req->rq_level = imp->imp_level; - rc = ptlrpc_queue_wait(req); - - if ( rc == 0 ) { - rsp = lustre_msg_buf(req->rq_repmsg, 0); - /* XXX do stuff */ - } - -out_desc: - ptlrpc_bulk_decref(desc); -out_req: - ptlrpc_req_finished(req); - RETURN(rc); -} - -static int ptlbd_bulk_timeout(void *data) -{ -/* struct ptlrpc_bulk_desc *desc = data;*/ - ENTRY; - - CERROR("ugh, timed out\n"); - - RETURN(1); -} - -void ptlbd_do_filp(struct file *filp, int op, struct ptlbd_niob *niobs, - int page_count, struct list_head *page_list) -{ - mm_segment_t old_fs; - struct list_head *pos; - ENTRY; - - old_fs = get_fs(); - set_fs(KERNEL_DS); - - list_for_each(pos, page_list) { - ssize_t ret; - struct page *page = list_entry(pos, struct page, list); - loff_t offset = (niobs->n_block_nr << PAGE_SHIFT) + - niobs->n_offset; - - if ( op == PTLBD_READ ) - ret = filp->f_op->read(filp, page_address(page), - niobs->n_length, &offset); - else - ret = filp->f_op->write(filp, page_address(page), - niobs->n_length, &offset); - - niobs++; - } - - set_fs(old_fs); - EXIT; -} - -int ptlbd_parse_req(struct ptlrpc_request *req) -{ - struct ptlbd_op *op; - struct ptlbd_niob *niob, *niobs; - struct ptlbd_rsp *rsp; - struct ptlrpc_bulk_desc *desc; - struct file *filp = req->rq_obd->u.ptlbd.filp; - struct l_wait_info lwi; - int size[1], wait_flag, i, page_count, rc; - struct list_head *pos, *n; - LIST_HEAD(tmp_pages); - ENTRY; - - rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); - if ( rc ) - RETURN(rc); - - op = lustre_msg_buf(req->rq_reqmsg, 0); - LASSERT(op->op_cmd == PTLBD_READ || op->op_cmd == PTLBD_WRITE); - - niobs = lustre_msg_buf(req->rq_reqmsg, 1); - page_count = req->rq_reqmsg->buflens[1] / sizeof(struct ptlbd_niob); - - desc = ptlrpc_prep_bulk(req->rq_connection); - if (desc == NULL) - GOTO(out, rc = -ENOMEM); - desc->bd_ptl_ev_hdlr = NULL; - desc->bd_portal = PTLBD_BULK_PORTAL; - - for ( i = 0, niob = niobs ; i < page_count; niob++, i++) { - struct ptlrpc_bulk_page *bulk = ptlrpc_prep_bulk_page(desc); - if (bulk == NULL) - GOTO(out_bulk, rc = -ENOMEM); - - bulk->bp_page = alloc_page(GFP_KERNEL); - if (bulk->bp_page == NULL) - GOTO(out_bulk, rc = -ENOMEM); - list_add(&bulk->bp_page->list, &tmp_pages); - - /* - * XXX what about the block number? - */ - bulk->bp_xid = niob->n_xid; - bulk->bp_buf = page_address(bulk->bp_page); - bulk->bp_buflen = niob->n_length; - } - - if ( op->op_cmd == PTLBD_READ ) { - ptlbd_do_filp(filp, PTLBD_READ, niobs, page_count, &tmp_pages); - rc = ptlrpc_bulk_put(desc); - wait_flag = PTL_BULK_FL_SENT; - } else { - rc = ptlrpc_bulk_get(desc); - wait_flag = PTL_BULK_FL_RCVD; - } - - if ( rc ) - GOTO(out_bulk, rc); - - /* this synchronization probably isn't good enough */ - lwi = LWI_TIMEOUT(obd_timeout * HZ, ptlbd_bulk_timeout, desc); - rc = l_wait_event(desc->bd_waitq, desc->bd_flags & wait_flag, &lwi); - - size[0] = sizeof(struct ptlbd_rsp); - rc = lustre_pack_msg(1, size, NULL, &req->rq_replen, &req->rq_repmsg); - if ( rc ) - GOTO(out, rc); - - rsp = lustre_msg_buf(req->rq_repmsg, 0); - if ( rsp == NULL ) - GOTO(out, rc = -EINVAL); - - ptlbd_do_filp(filp, PTLBD_WRITE, niobs, page_count, &tmp_pages); - - rsp->r_error_cnt = 42; - rsp->r_status = 69; - - req->rq_status = 0; /* XXX */ - ptlrpc_reply(req->rq_svc, req); - -out_bulk: - list_for_each_safe(pos, n, &tmp_pages) { - struct page *page = list_entry(pos, struct page, list); - list_del(&page->list); - __free_page(page); - } - ptlrpc_bulk_decref(desc); -out: - RETURN(rc); -} diff --git a/lustre/ptlbd/server.c b/lustre/ptlbd/server.c deleted file mode 100644 index 793354d..0000000 --- a/lustre/ptlbd/server.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) 2002, 2003 Cluster File Systems, Inc. - * Author: Zach Brown - * - * 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_PTLBD - -#include -#include -#include -#include -#include - -static int ptlbd_sv_already_setup = 1; - -static int ptlbd_sv_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - struct ptlbd_obd *ptlbd = &obddev->u.ptlbd; - int rc; - ENTRY; - - ptlbd->filp = filp_open("/tmp/ptlbd-backing-file-la-la-la", - O_RDWR|O_CREAT, 0600); - if ( IS_ERR(ptlbd->filp) ) - RETURN(PTR_ERR(ptlbd->filp)); - - ptlbd->ptlbd_service = - ptlrpc_init_svc(PTLBD_NEVENTS, PTLBD_NBUFS, PTLBD_BUFSIZE, - PTLBD_MAXREQSIZE, PTLBD_REQUEST_PORTAL, - PTLBD_REPLY_PORTAL, - ptlbd_parse_req, "ptlbd_sv"); - - if (ptlbd->ptlbd_service == NULL) - GOTO(out_filp, rc = -ENOMEM); - - rc = ptlrpc_start_thread(obddev, ptlbd->ptlbd_service, "ptldb"); - if (rc != 0) - GOTO(out_thread, rc); - - ptlbd_sv_already_setup = 1; - - RETURN(0); - -out_thread: - ptlrpc_stop_all_threads(ptlbd->ptlbd_service); - ptlrpc_unregister_service(ptlbd->ptlbd_service); -out_filp: - filp_close(ptlbd->filp, NULL); - - RETURN(rc); -} - -static int ptlbd_sv_cleanup(struct obd_device *obddev) -{ - struct ptlbd_obd *ptlbd = &obddev->u.ptlbd; - ENTRY; - - /* XXX check for state */ - - ptlrpc_stop_all_threads(ptlbd->ptlbd_service); - ptlrpc_unregister_service(ptlbd->ptlbd_service); - if ( ! IS_ERR(ptlbd->filp) ) - filp_close(ptlbd->filp, NULL); - - ptlbd_sv_already_setup = 0; - RETURN(0); -} - -static struct obd_ops ptlbd_sv_obd_ops = { - o_owner: THIS_MODULE, - o_setup: ptlbd_sv_setup, - o_cleanup: ptlbd_sv_cleanup, -}; - -int ptlbd_sv_init(void) -{ - struct lprocfs_static_vars lvars; - - lprocfs_init_vars(&lvars); - return class_register_type(&ptlbd_sv_obd_ops, lvars.module_vars, - OBD_PTLBD_SV_DEVICENAME); -} - -void ptlbd_sv_exit(void) -{ - class_unregister_type(OBD_PTLBD_SV_DEVICENAME); -} 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 446f110..0000000 --- a/lustre/ptlrpc/Makefile.am +++ /dev/null @@ -1,19 +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 LIBLUSTRE -lib_LIBRARIES = libptlrpc.a -libptlrpc_a_SOURCES = client.c niobuf.c pack_generic.c recovd.c recover.c connection.c rpc.c events.c # lproc_ptlrpc.c service.c -else -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 -endif - -include $(top_srcdir)/Rules diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c deleted file mode 100644 index 7d80d5f..0000000 --- a/lustre/ptlrpc/client.c +++ /dev/null @@ -1,952 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#define DEBUG_SUBSYSTEM S_RPC -#ifndef __KERNEL__ -#include -#include -#include -#endif - -#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; -} - -struct obd_uuid *ptlrpc_req_to_uuid(struct ptlrpc_request *req) -{ - return &req->rq_connection->c_remote_uuid; -} - -struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *uuid) -{ - struct ptlrpc_connection *c; - struct ptlrpc_peer peer; - int err; - - err = ptlrpc_uuid_to_peer(uuid, &peer); - if (err != 0) { - CERROR("cannot find peer %s!\n", uuid->uuid); - return NULL; - } - - c = ptlrpc_get_connection(&peer, uuid); - if (c) { - memcpy(c->c_remote_uuid.uuid, - uuid->uuid, sizeof(c->c_remote_uuid.uuid)); - c->c_epoch++; - } - - CDEBUG(D_INFO, "%s -> %p\n", uuid->uuid, c); - - return c; -} - -void ptlrpc_readdress_connection(struct ptlrpc_connection *conn,struct obd_uuid *uuid) -{ - struct ptlrpc_peer peer; - int err; - - err = ptlrpc_uuid_to_peer (uuid, &peer); - if (err != 0) { - CERROR("cannot find peer %s!\n", uuid->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)); - - if (atomic_read(&desc->bd_refcount) != 0) - CERROR("freeing desc %p with refcount %d!\n", desc, - atomic_read(&desc->bd_refcount)); - - 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 bulk I/O on the MD hasn't - * even started yet. XXX where do we kunmup the thing? - * - * If it fail with PTL_MD_BUSY, then the network is still - * reading/writing the buffers and we must wait for it to - * complete (which it will within finite time, most - * probably with failure; we really need portals error - * events to detect that). - * - * Otherwise (PTL_INV_MD) it completed after the bd_flags - * test above! - */ - if (PtlMDUnlink(desc->bd_md_h) != PTL_OK) { - CERROR("Near-miss on OST %s -- need to adjust " - "obd_timeout?\n", - desc->bd_connection->c_remote_uuid.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.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; - struct ptlrpc_request *request; - int rc; - ENTRY; - - LASSERT((unsigned long)imp > 0x1000); - conn = imp->imp_connection; - - 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, now 249 */ - 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); - - 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; - } - - /* We must take it off the imp_replay_list first. Otherwise, we'll set - * request->rq_reqmsg to NULL while osc_close is dereferencing it. */ - if (request->rq_import) { - unsigned long flags = 0; - if (!locked) - spin_lock_irqsave(&request->rq_import->imp_lock, flags); - list_del_init(&request->rq_list); - if (!locked) - spin_unlock_irqrestore(&request->rq_import->imp_lock, - flags); - } - - 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.uuid, - request->rq_import->imp_client->cli_request_portal, - atomic_read (&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; - } - - 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 (request == (void *)(long)(0x5a5a5a5a5a5a5a5a)) { - CERROR("dereferencing freed request (bug 575)\n"); - LBUG(); - RETURN(1); - } - - DEBUG_REQ(D_INFO, request, "refcount now %u", - atomic_read(&request->rq_refcount) - 1); - - if (atomic_dec_and_test(&request->rq_refcount)) { - __ptlrpc_free_req(request, locked); - RETURN(1); - } - - 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); - /* Store transno in reqmsg for replay. */ - req->rq_reqmsg->transno = req->rq_repmsg->transno; - req->rq_flags |= PTL_RPC_FL_REPLIED; - GOTO(out, rc = 1); - } - - if (req->rq_flags & PTL_RPC_FL_RESEND) { - 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 (%d)", err); - RETURN(err ? err : -EINVAL); - } - - if (err < 0) { - DEBUG_REQ(D_INFO, 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. */ -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. */ - if (PtlMEUnlink(request->rq_reply_me_h) != PTL_OK) - RETURN(0); - OBD_FREE(request->rq_reply_md.start, request->rq_replen); - - memset(&request->rq_reply_me_h, 0, sizeof(request->rq_reply_me_h)); - request->rq_reply_md.start = NULL; - request->rq_repmsg = NULL; - 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; - - LASSERT(imp != NULL); - -#ifdef CONFIG_SMP - LASSERT(spin_is_locked(&imp->imp_lock)); -#endif - - CDEBUG(D_HA, "%s: committing for last_committed "LPU64"\n", - imp->imp_obd->obd_name, 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); - list_del_init(&req->rq_list); - __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; - unsigned long flags; - ENTRY; - - LASSERT(conn); - - spin_lock_irqsave(&imp->imp_lock, flags); - 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_irqrestore(&imp->imp_lock, flags); - - EXIT; - return; -} - -void ptlrpc_continue_req(struct ptlrpc_request *req) -{ - 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); -} - -void ptlrpc_resend_req(struct ptlrpc_request *req) -{ - 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); -} - -void ptlrpc_restart_req(struct ptlrpc_request *req) -{ - 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); -} - -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"); - ptlrpc_abort(req); - req->rq_flags |= PTL_RPC_FL_TIMEOUT; - - if (!req->rq_import) { - DEBUG_REQ(D_HA, req, "NULL import; already cleaned up?"); - RETURN(1); - } - - 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); - - recovd_conn_fail(req->rq_import->imp_connection); - - /* 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); - 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 */ -} - -struct ptlrpc_request *ptlrpc_request_addref(struct ptlrpc_request *req) -{ - ENTRY; - atomic_inc(&req->rq_refcount); - RETURN(req); -} - -void ptlrpc_retain_replayable_request(struct ptlrpc_request *req, - struct obd_import *imp) -{ - struct list_head *tmp; - -#ifdef CONFIG_SMP - LASSERT(spin_is_locked(&imp->imp_lock)); -#endif - - LASSERT(imp->imp_flags & IMP_REPLAYABLE); - /* Balanced in ptlrpc_free_committed, usually. */ - ptlrpc_request_addref(req); - list_for_each_prev(tmp, &imp->imp_replay_list) { - struct ptlrpc_request *iter = - list_entry(tmp, struct ptlrpc_request, rq_list); - - /* We may have duplicate transnos if we create and then - * open a file, or for closes retained if to match creating - * opens, so use req->rq_xid as a secondary key. - * (See bugs 684, 685, and 428.) - */ - if (iter->rq_transno > req->rq_transno) - continue; - - if (iter->rq_transno == req->rq_transno) { - LASSERT(iter->rq_xid != req->rq_xid); - if (iter->rq_xid > req->rq_xid) - continue; - } - - list_add(&req->rq_list, &iter->rq_list); - return; - } - - list_add_tail(&req->rq_list, &imp->imp_replay_list); -} - -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; - unsigned int flags; - ENTRY; - - init_waitqueue_head(&req->rq_wait_for_rep); - - req->rq_xid = HTON__u32(ptlrpc_next_xid()); - - /* for distributed debugging */ - req->rq_reqmsg->status = HTON__u32(current->pid); - CDEBUG(D_RPCTRACE, "Sending RPC pid:xid:nid:opc %d:"LPU64":%s:"LPX64 - ":%d\n", NTOH__u32(req->rq_reqmsg->status), req->rq_xid, - conn->c_peer.peer_ni->pni_name, conn->c_peer.peer_nid, - NTOH__u32(req->rq_reqmsg->opc)); - - spin_lock_irqsave(&imp->imp_lock, flags); - - /* - * If the import has been invalidated (such as by an OST failure), the - * request must fail with -EIO. - */ - if (req->rq_import->imp_flags & IMP_INVALID) { - DEBUG_REQ(D_ERROR, req, "IMP_INVALID:"); - spin_unlock_irqrestore(&imp->imp_lock, flags); - RETURN(-EIO); - } - - if (req->rq_level > imp->imp_level) { - list_del(&req->rq_list); - list_add_tail(&req->rq_list, &imp->imp_delayed_list); - spin_unlock_irqrestore(&imp->imp_lock, flags); - - 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); - - if (req->rq_flags & PTL_RPC_FL_ERR) - rc = -EIO; - - if (!req->rq_import) - RETURN(rc); - - spin_lock_irqsave(&imp->imp_lock, flags); - list_del_init(&req->rq_list); - - if (rc) { - spin_unlock_irqrestore(&imp->imp_lock, flags); - RETURN(rc); - } - - CERROR("process %d resumed\n", current->pid); - } - resend: - - LASSERT(list_empty(&req->rq_list)); - list_add_tail(&req->rq_list, &imp->imp_sending_list); - spin_unlock_irqrestore(&imp->imp_lock, flags); - 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(obd_timeout * HZ, expired_request, - interrupted_request, req); - } -#ifdef __KERNEL__ - l_wait_event(req->rq_wait_for_rep, ptlrpc_check_reply(req), &lwi); -#else - { - extern int reply_in_callback(ptl_event_t *ev); - ptl_event_t reply_ev; - PtlEQWait(req->rq_connection->c_peer.peer_ni->pni_reply_in_eq_h, &reply_ev); - reply_in_callback(&reply_ev); - } -#endif - - DEBUG_REQ(D_NET, req, "-- done sleeping"); - - spin_lock_irqsave(&imp->imp_lock, flags); - list_del_init(&req->rq_list); - spin_unlock_irqrestore(&imp->imp_lock, flags); - - 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) { - if (req->rq_flags & PTL_RPC_FL_NO_RESEND) { - ptlrpc_abort(req); /* clean up reply buffers */ - req->rq_flags &= ~PTL_RPC_FL_NO_RESEND; - GOTO(out, rc = -ETIMEDOUT); - } - req->rq_flags &= ~PTL_RPC_FL_RESEND; - lustre_msg_add_flags(req->rq_reqmsg, MSG_RESENT); - DEBUG_REQ(D_HA, req, "resending: "); - spin_lock_irqsave(&imp->imp_lock, flags); - 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 - DEBUG_REQ(D_NET, req, "status %d", req->rq_repmsg->status); - - /* We're a rejected connection, need to invalidate and rebuild. */ - if (req->rq_repmsg->status == -ENOTCONN) { - spin_lock_irqsave(&imp->imp_lock, flags); - /* If someone else is reconnecting us (CONN_RECOVD) or has - * already completed it (handle mismatch), then we just need - * to get out. - */ - if (imp->imp_level == LUSTRE_CONN_RECOVD || - imp->imp_handle.addr != req->rq_reqmsg->addr || - imp->imp_handle.cookie != req->rq_reqmsg->cookie) { - spin_unlock_irqrestore(&imp->imp_lock, flags); - GOTO(out, rc = -EIO); - } - imp->imp_level = LUSTRE_CONN_RECOVD; - spin_unlock_irqrestore(&imp->imp_lock, flags); - rc = imp->imp_recover(imp, PTLRPC_RECOVD_PHASE_NOTCONN); - if (rc) - LBUG(); - GOTO(out, rc = -EIO); - } - - rc = ptlrpc_check_status(req); - - if (req->rq_import->imp_flags & IMP_REPLAYABLE) { - spin_lock_irqsave(&imp->imp_lock, flags); - if ((req->rq_flags & PTL_RPC_FL_REPLAY || req->rq_transno != 0) - && rc >= 0) { - ptlrpc_retain_replayable_request(req, imp); - } - - if (req->rq_transno > imp->imp_max_transno) { - imp->imp_max_transno = req->rq_transno; - } - - /* Replay-enabled imports return commit-status information. */ - if (req->rq_repmsg->last_committed) { - imp->imp_peer_committed_transno = - req->rq_repmsg->last_committed; - } - ptlrpc_free_committed(imp); - spin_unlock_irqrestore(&imp->imp_lock, flags); - } - - EXIT; - out: - return rc; -} - -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_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); -} - -/* XXX looks a lot like super.c:invalidate_request_list, don't it? */ -void ptlrpc_abort_inflight(struct obd_import *imp, int dying_import) -{ - unsigned long flags; - 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. - */ - if ((imp->imp_flags & IMP_REPLAYABLE) == 0) { - spin_lock_irqsave(&imp->imp_lock, flags); - imp->imp_flags |= IMP_INVALID; - spin_unlock_irqrestore(&imp->imp_lock, flags); - } - - 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; - if (dying_import) - req->rq_import = NULL; - 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; - if (dying_import) - req->rq_import = NULL; - wake_up(&req->rq_wait_for_rep); - } -} diff --git a/lustre/ptlrpc/connection.c b/lustre/ptlrpc/connection.c deleted file mode 100644 index 8f2cc2d..0000000 --- a/lustre/ptlrpc/connection.c +++ /dev/null @@ -1,181 +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 -#ifdef __KERNEL__ -#include -#include -#include -#else -#include -#endif - -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, - struct obd_uuid *uuid) -{ - struct obd_uuid zero_uuid; - memset(&zero_uuid, 0, sizeof(zero_uuid)); - - if (uuid) - return memcmp(c->c_remote_uuid.uuid, uuid->uuid, - sizeof(uuid->uuid)); - - return memcmp(c->c_remote_uuid.uuid, &zero_uuid, sizeof(zero_uuid)); -} - -struct ptlrpc_connection *ptlrpc_get_connection(struct ptlrpc_peer *peer, - struct obd_uuid *uuid) -{ - struct list_head *tmp, *pos; - struct ptlrpc_connection *c; - ENTRY; - - CDEBUG(D_INFO, "peer is "LPX64" on %s\n", - peer->peer_nid, peer->peer_ni->pni_name); - - spin_lock(&conn_lock); - list_for_each(tmp, &conn_list) { - c = list_entry(tmp, struct ptlrpc_connection, c_link); - if (peer->peer_nid == c->c_peer.peer_nid && - peer->peer_ni == c->c_peer.peer_ni && - !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 (peer->peer_nid == c->c_peer.peer_nid && - peer->peer_ni == c->c_peer.peer_ni && - !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->uuid) - obd_str2uuid(&c->c_remote_uuid, 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); - memcpy(&c->c_peer, peer, sizeof(c->c_peer)); - spin_lock_init(&c->c_lock); - - ptlrpc_connection_addref(c); - - 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 to "LPX64" on %s\n", - c, atomic_read(&c->c_refcount), c->c_peer.peer_nid, - c->c_peer.peer_ni->pni_name); - - 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; - atomic_inc(&c->c_refcount); - CDEBUG (D_INFO, "connection=%p refcount %d to "LPX64" on %s\n", - c, atomic_read(&c->c_refcount), c->c_peer.peer_nid, - c->c_peer.peer_ni->pni_name); - 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="LPX64" on %s)\n", - c, c->c_remote_uuid.uuid, atomic_read(&c->c_refcount), - c->c_peer.peer_nid, c->c_peer.peer_ni->pni_name); - 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 4a6eb67..0000000 --- a/lustre/ptlrpc/events.c +++ /dev/null @@ -1,499 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#define DEBUG_SUBSYSTEM S_RPC - -#ifdef __KERNEL__ -#include -#else -#include -#endif -#include -#include - -struct ptlrpc_ni ptlrpc_interfaces[NAL_MAX_NR]; -int ptlrpc_ninterfaces; - -/* - * 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 if (ev->type == PTL_EVENT_ACK) { - struct ptlrpc_request *req = ev->mem_desc.user_ptr; - if (req->rq_flags & PTL_RPC_FL_WANT_ACK) { - req->rq_flags &= ~PTL_RPC_FL_WANT_ACK; - wake_up(&req->rq_wait_for_rep); - } else { - DEBUG_REQ(D_ERROR, req, - "ack received for reply, not wanted"); - } - } else { - // XXX make sure we understand all events - CERROR("Unknown event %d\n", ev->type); - LBUG(); - } - - RETURN(1); -} - -/* - * Wake up the thread waiting for the reply once it comes in. - */ -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_srv_ni *srv_ni = rqbd->rqbd_srv_ni; - struct ptlrpc_service *service = srv_ni->sni_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(&srv_ni->sni_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(&srv_ni->sni_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_put_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)) { - void (*event_handler)(struct ptlrpc_bulk_desc *); - - 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); - } - - /* We need to make a note of whether there's an event handler - * before we call wake_up, because if there is no event handler, - * 'desc' might be freed before we're scheduled again. */ - event_handler = desc->bd_ptl_ev_hdlr; - - desc->bd_flags |= PTL_BULK_FL_SENT; - wake_up(&desc->bd_waitq); - if (event_handler) { - LASSERT(desc->bd_ptl_ev_hdlr == event_handler); - event_handler(desc); - } - } - - RETURN(0); -} - -static int bulk_put_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; - void (*event_handler)(struct ptlrpc_bulk_desc *); - ENTRY; - - LASSERT(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); - - /* We need to make a note of whether there's an event handler - * before we call wake_up, because if there is no event - * handler, 'desc' might be freed before we're scheduled again. */ - event_handler = desc->bd_ptl_ev_hdlr; - - desc->bd_flags |= PTL_BULK_FL_RCVD; - wake_up(&desc->bd_waitq); - if (event_handler) { - LASSERT(desc->bd_ptl_ev_hdlr == event_handler); - event_handler(desc); - } - - RETURN(1); -} - -static int bulk_get_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; - ptl_size_t total = 0; - void (*event_handler)(struct ptlrpc_bulk_desc *); - ENTRY; - - LASSERT(ev->type == PTL_EVENT_GET); - - /* 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); - - /* We need to make a note of whether there's an event handler - * before we call wake_up, because if there is no event - * handler, 'desc' might be freed before we're scheduled again. */ - event_handler = desc->bd_ptl_ev_hdlr; - - desc->bd_flags |= PTL_BULK_FL_SENT; - wake_up(&desc->bd_waitq); - if (event_handler) { - LASSERT(desc->bd_ptl_ev_hdlr == event_handler); - event_handler(desc); - } - - RETURN(1); -} - - -static int bulk_get_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; - ENTRY; - - CDEBUG(D_NET, "got %s event %d\n", - (ev->type == PTL_EVENT_SENT) ? "SENT" : - (ev->type == PTL_EVENT_REPLY) ? "REPLY" : "UNEXPECTED", - ev->type); - - LASSERT(ev->type == PTL_EVENT_SENT || ev->type == PTL_EVENT_REPLY); - - 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)) { - void (*event_handler)(struct ptlrpc_bulk_desc *); - - 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); - } - - /* We need to make a note of whether there's an event handler - * before we call wake_up, because if there is no event handler, - * 'desc' might be freed before we're scheduled again. */ - event_handler = desc->bd_ptl_ev_hdlr; - - desc->bd_flags |= PTL_BULK_FL_RCVD; - wake_up(&desc->bd_waitq); - if (event_handler) { - LASSERT(desc->bd_ptl_ev_hdlr == event_handler); - event_handler(desc); - } - } - - RETURN(0); -} - -int ptlrpc_uuid_to_peer (struct obd_uuid *uuid, struct ptlrpc_peer *peer) -{ - struct ptlrpc_ni *pni; - struct lustre_peer lpeer; - int i; - int rc = lustre_uuid_to_peer (uuid->uuid, &lpeer); - - if (rc != 0) - RETURN (rc); - - for (i = 0; i < ptlrpc_ninterfaces; i++) { - pni = &ptlrpc_interfaces[i]; - - if (!memcmp (&lpeer.peer_ni, &pni->pni_ni_h, - sizeof (lpeer.peer_ni))) { - peer->peer_nid = lpeer.peer_nid; - peer->peer_ni = pni; - return (0); - } - } - - CERROR ("Can't find ptlrpc interface for "LPX64" ni handle %08lx %08lx\n", - lpeer.peer_nid, lpeer.peer_ni.nal_idx, lpeer.peer_ni.handle_idx); - return (-ENOENT); -} - -void ptlrpc_ni_fini (struct ptlrpc_ni *pni) -{ - PtlEQFree(pni->pni_request_out_eq_h); - PtlEQFree(pni->pni_reply_out_eq_h); - PtlEQFree(pni->pni_reply_in_eq_h); - PtlEQFree(pni->pni_bulk_put_source_eq_h); - PtlEQFree(pni->pni_bulk_put_sink_eq_h); - PtlEQFree(pni->pni_bulk_get_source_eq_h); - PtlEQFree(pni->pni_bulk_get_sink_eq_h); - - inter_module_put(pni->pni_name); -} - -int ptlrpc_ni_init (char *name, struct ptlrpc_ni *pni) -{ - int rc; - ptl_handle_ni_t *nip; - - nip = (ptl_handle_ni_t *)inter_module_get (name); - if (nip == NULL) { - CDEBUG (D_NET, "Network interface %s not loaded\n", name); - return (-ENOENT); - } - - CDEBUG (D_NET, "init %s: nal_idx %ld\n", name, nip->nal_idx); - - pni->pni_name = name; - pni->pni_ni_h = *nip; - - ptl_set_inv_handle (&pni->pni_request_out_eq_h); - ptl_set_inv_handle (&pni->pni_reply_out_eq_h); - ptl_set_inv_handle (&pni->pni_reply_in_eq_h); - ptl_set_inv_handle (&pni->pni_bulk_put_source_eq_h); - ptl_set_inv_handle (&pni->pni_bulk_put_sink_eq_h); - ptl_set_inv_handle (&pni->pni_bulk_get_source_eq_h); - ptl_set_inv_handle (&pni->pni_bulk_get_sink_eq_h); - - /* NB We never actually PtlEQGet() out of these events queues since - * we're only interested in the event callback, so we can just let - * them wrap. Their sizes aren't a big deal, apart from providing - * a little history for debugging... */ - - rc = PtlEQAlloc(pni->pni_ni_h, 1024, request_out_callback, - &pni->pni_request_out_eq_h); - if (rc != PTL_OK) - GOTO (fail, rc = -ENOMEM); - - rc = PtlEQAlloc(pni->pni_ni_h, 1024, reply_out_callback, - &pni->pni_reply_out_eq_h); - if (rc != PTL_OK) - GOTO (fail, rc = -ENOMEM); - - rc = PtlEQAlloc(pni->pni_ni_h, 1024, reply_in_callback, - &pni->pni_reply_in_eq_h); - if (rc != PTL_OK) - GOTO (fail, rc = -ENOMEM); - - rc = PtlEQAlloc(pni->pni_ni_h, 1024, bulk_put_source_callback, - &pni->pni_bulk_put_source_eq_h); - if (rc != PTL_OK) - GOTO (fail, rc = -ENOMEM); - - rc = PtlEQAlloc(pni->pni_ni_h, 1024, bulk_put_sink_callback, - &pni->pni_bulk_put_sink_eq_h); - if (rc != PTL_OK) - GOTO (fail, rc = -ENOMEM); - - rc = PtlEQAlloc(pni->pni_ni_h, 1024, bulk_get_source_callback, - &pni->pni_bulk_get_source_eq_h); - if (rc != PTL_OK) - GOTO (fail, rc = -ENOMEM); - - rc = PtlEQAlloc(pni->pni_ni_h, 1024, bulk_get_sink_callback, - &pni->pni_bulk_get_sink_eq_h); - if (rc != PTL_OK) - GOTO (fail, rc = -ENOMEM); - - return (0); - fail: - CERROR ("Failed to initialise network interface %s: %d\n", - name, rc); - - /* OK to do complete teardown since we invalidated the handles above... */ - ptlrpc_ni_fini (pni); - return (rc); -} - -int ptlrpc_init_portals(void) -{ - /* Add new portals network interface names here. - * Order is irrelevent! */ - char *ni_names[] = { "kqswnal_ni", - "kgmnal_ni", - "ksocknal_ni", - "ktoenal_ni", - "tcpnal_ni", - NULL }; - int rc; - int i; - - LASSERT (ptlrpc_ninterfaces == 0); - - for (i = 0; ni_names[i] != NULL; i++) { - LASSERT (ptlrpc_ninterfaces < - sizeof (ptlrpc_interfaces)/sizeof (ptlrpc_interfaces[0])); - - rc = ptlrpc_ni_init (ni_names[i], - &ptlrpc_interfaces[ptlrpc_ninterfaces]); - if (rc == 0) - ptlrpc_ninterfaces++; - } - - if (ptlrpc_ninterfaces == 0) { - CERROR("network initialisation failed: is a NAL module loaded?\n"); - return -EIO; - } - return 0; -} - -void ptlrpc_exit_portals(void) -{ - while (ptlrpc_ninterfaces > 0) - ptlrpc_ni_fini (&ptlrpc_interfaces[--ptlrpc_ninterfaces]); -} diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c deleted file mode 100644 index 1b3532e..0000000 --- a/lustre/ptlrpc/lproc_ptlrpc.c +++ /dev/null @@ -1,41 +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 - -#ifndef LPROCFS -struct lprocfs_vars lprocfs_obd_vars[] = { {0} }; -struct lprocfs_vars lprocfs_module_vars[] = { {0} }; -#else -struct lprocfs_vars lprocfs_obd_vars[] = { - { "uuid", lprocfs_rd_uuid, 0, 0}, - { 0 } -}; - -struct lprocfs_vars lprocfs_module_vars[] = { - { "num_refs", lprocfs_rd_numrefs, 0, 0}, - { 0 } -}; - -#endif /* LPROCFS */ -LPROCFS_INIT_VARS(lprocfs_module_vars, lprocfs_obd_vars) diff --git a/lustre/ptlrpc/niobuf.c b/lustre/ptlrpc/niobuf.c deleted file mode 100644 index 62a76c4..0000000 --- a/lustre/ptlrpc/niobuf.c +++ /dev/null @@ -1,630 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#define DEBUG_SUBSYSTEM S_RPC -#ifndef __KERNEL__ -#include -#include -#endif -#include -#include -#include -#include - -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; - ptl_ack_req_t ack_req; - - LASSERT(conn); - CDEBUG (D_INFO, "conn=%p ni %s nid "LPX64" on %s\n", - conn, conn->c_peer.peer_ni->pni_name, - conn->c_peer.peer_nid, conn->c_peer.peer_ni->pni_name); - - 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 = conn->c_peer.peer_ni->pni_request_out_eq_h; - 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 = conn->c_peer.peer_ni->pni_reply_out_eq_h; - break; - default: - LBUG(); - return -1; /* notreached */ - } - if (request->rq_flags & PTL_RPC_FL_WANT_ACK) { - request->rq_req_md.threshold = 2; /* SENT and ACK */ - ack_req = PTL_ACK_REQ; - } else { - request->rq_req_md.threshold = 1; - ack_req = PTL_NOACK_REQ; - } - request->rq_req_md.options = PTL_MD_OP_PUT; - request->rq_req_md.user_ptr = request; - - if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_ACK | OBD_FAIL_ONCE)) { - request->rq_req_md.options |= PTL_MD_ACK_DISABLE; - obd_fail_loc |= OBD_FAIL_ONCE | OBD_FAILED; - } - - rc = PtlMDBind(conn->c_peer.peer_ni->pni_ni_h, 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, ack_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_bulk_put(struct ptlrpc_bulk_desc *desc) -{ - int rc; - struct ptlrpc_peer *peer; - 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); - - peer = &desc->bd_connection->c_peer; - - desc->bd_md.start = iov; - desc->bd_md.niov = 0; - desc->bd_md.length = 0; - desc->bd_md.eventq = peer->peer_ni->pni_bulk_put_source_eq_h; - 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; - if (iov[desc->bd_md.niov].iov_len <= 0) { - CERROR("bad bp_buflen[%d] @ %p: %d\n", desc->bd_md.niov, - bulk->bp_buf, bulk->bp_buflen); - CERROR("desc: xid %u, pages %d, ptl %d, ref %d\n", - xid, desc->bd_page_count, desc->bd_portal, - atomic_read(&desc->bd_refcount)); - LBUG(); - } - 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(peer->peer_ni->pni_ni_h, 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 = peer->peer_nid; - remote_id.pid = 0; - - CDEBUG(D_NET, "Sending %u pages %u bytes to portal %d on %s " - "nid "LPX64" pid %d xid %d\n", - desc->bd_md.niov, desc->bd_md.length, - desc->bd_portal, peer->peer_ni->pni_name, - 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_bulk_get(struct ptlrpc_bulk_desc *desc) -{ - int rc; - struct ptlrpc_peer *peer; - 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); - - peer = &desc->bd_connection->c_peer; - - desc->bd_md.start = iov; - desc->bd_md.niov = 0; - desc->bd_md.length = 0; - desc->bd_md.eventq = peer->peer_ni->pni_bulk_get_sink_eq_h; - desc->bd_md.threshold = 2; /* SENT and REPLY */ - desc->bd_md.options = PTL_MD_OP_GET | 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; - if (iov[desc->bd_md.niov].iov_len <= 0) { - CERROR("bad bulk %p bp_buflen[%d] @ %p: %d\n", bulk, - desc->bd_md.niov, bulk->bp_buf, bulk->bp_buflen); - CERROR("desc %p: xid %u, pages %d, ptl %d, ref %d\n", - desc, xid, desc->bd_page_count, desc->bd_portal, - atomic_read(&desc->bd_refcount)); - LBUG(); - } - 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(peer->peer_ni->pni_ni_h, 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 on %s " - "nid "LPX64" pid %d xid %d\n", - desc->bd_md.niov, desc->bd_md.length, - desc->bd_portal, peer->peer_ni->pni_name, - remote_id.nid, remote_id.pid, xid); - - rc = PtlGet(desc->bd_md_h, remote_id, desc->bd_portal, 0, xid, 0); - if (rc != PTL_OK) { - CERROR("PtlGet("LPU64", %d, %d) failed: %d\n", - remote_id.nid, desc->bd_portal, xid, rc); - PtlMDUnlink(desc->bd_md_h); - LBUG(); - RETURN(rc); - } - - RETURN(0); -} - -static int ptlrpc_register_bulk_shared(struct ptlrpc_bulk_desc *desc) -{ - struct ptlrpc_peer *peer; - 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); - - peer = &desc->bd_connection->c_peer; - - desc->bd_md.start = iov; - desc->bd_md.niov = 0; - desc->bd_md.length = 0; - desc->bd_md.threshold = 1; - desc->bd_md.user_ptr = desc; - - 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(peer->peer_ni->pni_ni_h, - 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 on %s\n", desc->bd_md.niov, desc->bd_md.length, - xid, desc->bd_portal, peer->peer_ni->pni_name); - - RETURN(0); - - cleanup: - ptlrpc_put_bulk_iov (desc, iov); - ptlrpc_abort_bulk(desc); - - return rc; -} - -int ptlrpc_register_bulk_get(struct ptlrpc_bulk_desc *desc) -{ - desc->bd_md.options = PTL_MD_OP_GET | PTL_MD_IOV; - desc->bd_md.eventq = - desc->bd_connection->c_peer.peer_ni->pni_bulk_get_source_eq_h; - - return ptlrpc_register_bulk_shared(desc); -} - -int ptlrpc_register_bulk_put(struct ptlrpc_bulk_desc *desc) -{ - desc->bd_md.options = PTL_MD_OP_PUT | PTL_MD_IOV; - desc->bd_md.eventq = - desc->bd_connection->c_peer.peer_ni->pni_bulk_put_sink_eq_h; - - return ptlrpc_register_bulk_shared(desc); -} - -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) -{ - LASSERT(list_empty(&desc->bd_set_chain)); - - ptlrpc_bulk_addref(desc); - atomic_inc(&set->brw_refcount); - desc->bd_brw_set = set; - list_add(&desc->bd_set_chain, &set->brw_desc_head); -} - -void obd_brw_set_del(struct ptlrpc_bulk_desc *desc) -{ - atomic_dec(&desc->bd_brw_set->brw_refcount); - list_del_init(&desc->bd_set_chain); - ptlrpc_bulk_decref(desc); -} - -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; - - 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) { - 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 */ - ptlrpc_request_addref(request); - if (request->rq_replen != 0) { - if (request->rq_reply_md.start != NULL) { - rc = PtlMEUnlink(request->rq_reply_me_h); - if (rc != PTL_OK && rc != PTL_INV_ME) { - CERROR("rc %d\n", rc); - LBUG(); - } - repbuf = (char *)request->rq_reply_md.start; - request->rq_repmsg = NULL; - } else { - OBD_ALLOC(repbuf, request->rq_replen); - if (!repbuf) { - LBUG(); - RETURN(ENOMEM); - } - } - - rc = PtlMEAttach(request->rq_connection->c_peer.peer_ni->pni_ni_h, - 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 = - request->rq_connection->c_peer.peer_ni->pni_reply_in_eq_h; - - 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 on %s\n", - request->rq_replen, request->rq_xid, - request->rq_reply_portal, - request->rq_connection->c_peer.peer_ni->pni_name); - } - - /* Clear any flags that may be present from previous sends, - * except for REPLAY, NO_RESEND and WANT_ACK. */ - request->rq_flags &= (PTL_RPC_FL_REPLAY | PTL_RPC_FL_NO_RESEND | - PTL_RPC_FL_WANT_ACK); - 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_srv_ni *srv_ni = rqbd->rqbd_srv_ni; - struct ptlrpc_service *service = srv_ni->sni_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); - - CDEBUG(D_NET, "PtlMEAttach: portal %d on %s h %lx.%lx\n", - service->srv_req_portal, srv_ni->sni_ni->pni_name, - srv_ni->sni_ni->pni_ni_h.nal_idx, - srv_ni->sni_ni->pni_ni_h.handle_idx); - - /* Attach the leading ME on which we build the ring */ - rc = PtlMEAttach(srv_ni->sni_ni->pni_ni_h, 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 = srv_ni->sni_eq_h; - - atomic_inc(&srv_ni->sni_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(&srv_ni->sni_nrqbds_receiving); - } -} diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c deleted file mode 100644 index 12be831..0000000 --- a/lustre/ptlrpc/pack_generic.c +++ /dev/null @@ -1,144 +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 -#ifndef __KERNEL__ -#include -#endif - -#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); - CERROR("bufcount: %d\n", m->bufcount); - for (i = 0; i < m->bufcount; i++) - CERROR("buffer %d length %d\n", i, m->buflens[i]); - 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 21cb3fe..0000000 --- a/lustre/ptlrpc/recovd.c +++ /dev/null @@ -1,372 +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 -#ifndef __KERNEL__ -#include -#include -#include -#else -#include -#endif - -#include -#include - -/* dump_connection_list, but shorter for nicer debugging logs */ -static void d_c_l(struct list_head *head) -{ - 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.uuid, - conn->c_recovd_data.rd_phase, - conn->c_recovd_data.rd_next_phase); - } -} - -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.uuid); - EXIT; - return; - } - CDEBUG(D_HA, - "conn %p/%s has recovery items %p/%p, making %p/%p\n", - conn, conn->c_remote_uuid.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.uuid); - spin_unlock(&recovd->recovd_lock); - EXIT; - return; - } - - CERROR("connection %p to %s nid "LPX64" on %s failed\n", conn, - conn->c_remote_uuid.uuid, conn->c_peer.peer_nid, - conn->c_peer.peer_ni->pni_name); - 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.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.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); -} - -#ifdef __KERNEL__ -static int recovd_main(void *arg) -{ - struct recovd_obd *recovd = (struct recovd_obd *)arg; - unsigned long flags; - ENTRY; - - lock_kernel(); - daemonize(); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - sigfillset(¤t->blocked); - recalc_sigpending(); -#else - spin_lock_irqsave(¤t->sigmask_lock, flags); - sigfillset(¤t->blocked); - recalc_sigpending(current); - spin_unlock_irqrestore(¤t->sigmask_lock, flags); -#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 = 0; /* initialize for Liblustre */ - - 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); -} -#else -int recovd_setup(struct recovd_obd *recovd) -{ - return 0; -} -#endif - -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 a1464a3..0000000 --- a/lustre/ptlrpc/recover.c +++ /dev/null @@ -1,282 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Portal-RPC reconnection and replay operations, for use in recovery. - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * 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 DEBUG_SUBSYSTEM S_RPC -#ifdef __KERNEL__ -#include -#include -#include -#else -#include -#endif - -#include -#include -#include - -int ptlrpc_reconnect_import(struct obd_import *imp, int rq_opc, - struct ptlrpc_request **reqptr) -{ - 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.uuid, obd->obd_uuid.uuid}; - struct ptlrpc_connection *conn = imp->imp_connection; - struct ptlrpc_request *req; - struct obd_export *ldlmexp; - struct lustre_handle old_hdl; - int rc; - - req = ptlrpc_prep_req(imp, rq_opc, 2, size, tmp); - if (!req) - RETURN(-ENOMEM); - req->rq_level = LUSTRE_CONN_NEW; - req->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); - req->rq_reqmsg->addr = (__u64)(unsigned long)ldlmexp; - req->rq_reqmsg->cookie = ldlmexp->exp_cookie; - rc = ptlrpc_queue_wait(req); - if (rc) { - CERROR("cannot connect to %s@%s: rc = %d\n", - cli->cl_target_uuid.uuid, conn->c_remote_uuid.uuid, rc); - GOTO(out_disc, rc); - } - if (lustre_msg_get_op_flags(req->rq_repmsg) & MSG_CONNECT_RECONNECT) { - memset(&old_hdl, 0, sizeof(old_hdl)); - if (!memcmp(&old_hdl.addr, &req->rq_repmsg->addr, - sizeof (old_hdl.addr)) && - !memcmp(&old_hdl.cookie, &req->rq_repmsg->cookie, - sizeof (old_hdl.cookie))) { - CERROR("%s@%s didn't like our handle "LPX64"/"LPX64 - ", failed\n", cli->cl_target_uuid.uuid, - conn->c_remote_uuid.uuid, - (__u64)(unsigned long)ldlmexp, - ldlmexp->exp_cookie); - GOTO(out_disc, rc = -ENOTCONN); - } - - old_hdl.addr = req->rq_repmsg->addr; - old_hdl.cookie = req->rq_repmsg->cookie; - if (memcmp(&imp->imp_handle, &old_hdl, sizeof(old_hdl))) { - CERROR("%s@%s changed handle from "LPX64"/"LPX64 - " to "LPX64"/"LPX64"; " - "copying, but this may foreshadow disaster\n", - cli->cl_target_uuid.uuid, - conn->c_remote_uuid.uuid, - old_hdl.addr, old_hdl.cookie, - imp->imp_handle.addr, imp->imp_handle.cookie); - imp->imp_handle.addr = req->rq_repmsg->addr; - imp->imp_handle.cookie = req->rq_repmsg->cookie; - GOTO(out_disc, rc = 0); - } - - CERROR("reconnected to %s@%s after partition\n", - cli->cl_target_uuid.uuid, conn->c_remote_uuid.uuid); - GOTO(out_disc, rc = 0); - } - - old_hdl = imp->imp_handle; - imp->imp_handle.addr = req->rq_repmsg->addr; - imp->imp_handle.cookie = req->rq_repmsg->cookie; - CERROR("reconnected to %s@%s ("LPX64"/"LPX64", was "LPX64"/" - LPX64")!\n", cli->cl_target_uuid.uuid, conn->c_remote_uuid.uuid, - imp->imp_handle.addr, imp->imp_handle.cookie, - old_hdl.addr, old_hdl.cookie); - GOTO(out_disc, rc = 0); - - out_disc: - *reqptr = req; - 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.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 rc = 0; - struct list_head *tmp, *pos; - struct ptlrpc_request *req; - unsigned long flags; - __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_irqsave(&imp->imp_lock, flags); - - ptlrpc_free_committed(imp); - - CDEBUG(D_HA, "import %p from %s has committed "LPD64"\n", - imp, imp->imp_obd->u.cli.cl_target_uuid.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); - - DEBUG_REQ(D_HA, req, "REPLAY:"); - - /* XXX locking WRT failure during replay? */ - rc = ptlrpc_replay_req(req); - - if (rc) { - CERROR("recovery replay error %d for req "LPD64"\n", - rc, req->rq_xid); - GOTO(out, rc); - } - } - - out: - spin_unlock_irqrestore(&imp->imp_lock, flags); - 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 && 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; - unsigned long flags; - __u64 committed = imp->imp_peer_committed_transno; - - ENTRY; - - spin_lock_irqsave(&imp->imp_lock, flags); - 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: - ptlrpc_restart_req(req); - break; - - case 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: - ptlrpc_resend_req(req); - break; - - default: - LBUG(); - } - } - - spin_unlock_irqrestore(&imp->imp_lock, flags); - RETURN(rc); -} - -void ptlrpc_wake_delayed(struct obd_import *imp) -{ - unsigned long flags; - struct list_head *tmp, *pos; - struct ptlrpc_request *req; - - spin_lock_irqsave(&imp->imp_lock, flags); - 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_irqrestore(&imp->imp_lock, flags); -} diff --git a/lustre/ptlrpc/rpc.c b/lustre/ptlrpc/rpc.c deleted file mode 100644 index 0f13acf..0000000 --- a/lustre/ptlrpc/rpc.c +++ /dev/null @@ -1,311 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (c) 2002, 2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#define EXPORT_SYMTAB -#define DEBUG_SUBSYSTEM S_RPC - -#ifdef __KERNEL__ -# include -# include -#else -# include -#endif -#include -#include -#include -#include -#include -#include -#include - -extern int ptlrpc_init_portals(void); -extern void ptlrpc_exit_portals(void); - -static __u32 ptlrpc_last_xid = 0; -static spinlock_t ptlrpc_last_xid_lock = SPIN_LOCK_UNLOCKED; - -__u32 ptlrpc_next_xid(void) -{ - __u32 tmp; - spin_lock(&ptlrpc_last_xid_lock); - tmp = ++ptlrpc_last_xid; - spin_unlock(&ptlrpc_last_xid_lock); - return tmp; -} - -int connmgr_setup(struct obd_device *obddev, obd_count len, void *buf) -{ - struct recovd_obd *recovd = &obddev->u.recovd; - int err; - ENTRY; - - memset(recovd, 0, sizeof(*recovd)); - - err = recovd_setup(recovd); - RETURN(err); -} - -int connmgr_cleanup(struct obd_device *dev) -{ - struct recovd_obd *recovd = &dev->u.recovd; - int err; - - err = recovd_cleanup(recovd); - RETURN(err); -} - -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 */ -#warning check buffer overflow in next line - if (!strcmp(conn->c_remote_uuid.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); - -#warning check buffer overflow in next line - if (!strcmp(conn->c_remote_uuid.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); - 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.uuid, data->ioc_inlbuf2); - obd_str2uuid(&conn->c_remote_uuid, data->ioc_inlbuf2); - } else { - CERROR("conn %p UUID %s reconnected\n", conn, - conn->c_remote_uuid.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, - struct obd_uuid *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) -{ - struct lprocfs_static_vars lvars; - int rc = 0; - - lprocfs_init_vars(&lvars); - rc = lprocfs_obd_attach(dev, lvars.obd_vars); - return rc; -} - -int conmgr_detach(struct obd_device *dev) -{ - return lprocfs_obd_detach(dev); -} - -/* use obd ops to offer management infrastructure */ -static struct obd_ops recovd_obd_ops = { - o_owner: THIS_MODULE, - 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 -}; - - - -__init int ptlrpc_init(void) -{ - struct lprocfs_static_vars lvars; - int rc; - ENTRY; - - rc = ptlrpc_init_portals(); - if (rc) - RETURN(rc); - ptlrpc_init_connection(); - - lprocfs_init_vars(&lvars); - rc = class_register_type(&recovd_obd_ops, lvars.module_vars, - LUSTRE_HA_NAME); - if (rc) - RETURN(rc); - ptlrpc_put_connection_superhack = ptlrpc_put_connection; - ptlrpc_abort_inflight_superhack = ptlrpc_abort_inflight; - RETURN(0); -} - -static void __exit ptlrpc_exit(void) -{ - class_unregister_type(LUSTRE_HA_NAME); - ptlrpc_exit_portals(); - ptlrpc_cleanup_connection(); -} - -/* rpc.c */ -EXPORT_SYMBOL(ptlrpc_next_xid); - -/* 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_bulk_put); -EXPORT_SYMBOL(ptlrpc_bulk_get); -EXPORT_SYMBOL(ptlrpc_register_bulk_put); -EXPORT_SYMBOL(ptlrpc_register_bulk_get); -EXPORT_SYMBOL(ptlrpc_abort_bulk); -EXPORT_SYMBOL(ptlrpc_reply); -EXPORT_SYMBOL(ptlrpc_error); -EXPORT_SYMBOL(ptlrpc_resend_req); -EXPORT_SYMBOL(ptl_send_rpc); -EXPORT_SYMBOL(ptlrpc_link_svc_me); -EXPORT_SYMBOL(obd_brw_set_free); -EXPORT_SYMBOL(obd_brw_set_new); -EXPORT_SYMBOL(obd_brw_set_add); -EXPORT_SYMBOL(obd_brw_set_del); - -/* client.c */ -EXPORT_SYMBOL(ptlrpc_init_client); -EXPORT_SYMBOL(ptlrpc_cleanup_client); -EXPORT_SYMBOL(ptlrpc_req_to_uuid); -EXPORT_SYMBOL(ptlrpc_uuid_to_connection); -EXPORT_SYMBOL(ptlrpc_queue_wait); -EXPORT_SYMBOL(ptlrpc_continue_req); -EXPORT_SYMBOL(ptlrpc_replay_req); -EXPORT_SYMBOL(ptlrpc_restart_req); -EXPORT_SYMBOL(ptlrpc_prep_req); -EXPORT_SYMBOL(ptlrpc_free_req); -EXPORT_SYMBOL(ptlrpc_abort); -EXPORT_SYMBOL(ptlrpc_req_finished); -EXPORT_SYMBOL(ptlrpc_request_addref); -EXPORT_SYMBOL(ptlrpc_prep_bulk); -EXPORT_SYMBOL(ptlrpc_free_bulk); -EXPORT_SYMBOL(ptlrpc_prep_bulk_page); -EXPORT_SYMBOL(ptlrpc_free_bulk_page); -EXPORT_SYMBOL(ll_brw_sync_wait); -EXPORT_SYMBOL(ptlrpc_abort_inflight); -EXPORT_SYMBOL(ptlrpc_retain_replayable_request); - -/* 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); - -#ifdef __KERNEL__ -MODULE_AUTHOR("Cluster File Systems, Inc. "); -MODULE_DESCRIPTION("Lustre Request Processor"); -MODULE_LICENSE("GPL"); - -module_init(ptlrpc_init); -module_exit(ptlrpc_exit); -#endif diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c deleted file mode 100644 index 112d01d..0000000 --- a/lustre/ptlrpc/service.c +++ /dev/null @@ -1,501 +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 -#ifndef __KERNEL__ -#include -#include -#endif -#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) -{ - struct ptlrpc_srv_ni *srv_ni; - int i; - int idx; - 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 (ptlrpc_ninterfaces > 0); - - for (i = 0; i < ptlrpc_ninterfaces; i++) { - idx = (svc->srv_interface_rover + i) % ptlrpc_ninterfaces; - srv_ni = &svc->srv_interfaces[idx]; - - LASSERT (ptl_is_valid_handle (&srv_ni->sni_eq_h)); - - rc = PtlEQGet(srv_ni->sni_eq_h, event); - switch (rc) - { - case PTL_OK: - /* next time start with the next interface */ - svc->srv_interface_rover = (idx+1) % ptlrpc_ninterfaces; - thread->t_flags |= SVC_EVENT; - GOTO(out, rc = 1); - - case PTL_EQ_EMPTY: - continue; - - default: - CERROR("BUG: PtlEQGet returned %d\n", rc); - LBUG(); - } - } - rc = 0; - 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, - svc_handler_t handler, char *name) -{ - int ssize; - int rc; - int i; - int j; - struct ptlrpc_service *service; - struct ptlrpc_srv_ni *srv_ni; - ENTRY; - - LASSERT (ptlrpc_ninterfaces > 0); - - ssize = offsetof (struct ptlrpc_service, - srv_interfaces[ptlrpc_ninterfaces]); - OBD_ALLOC(service, ssize); - if (service == NULL) - 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; - - service->srv_rep_portal = rep_portal; - service->srv_req_portal = req_portal; - service->srv_handler = handler; - service->srv_interface_rover = 0; - - /* First initialise enough for early teardown */ - for (i = 0; i < ptlrpc_ninterfaces; i++) { - srv_ni = &service->srv_interfaces[i]; - - srv_ni->sni_service = service; - srv_ni->sni_ni = &ptlrpc_interfaces[i]; - ptl_set_inv_handle (&srv_ni->sni_eq_h); - INIT_LIST_HEAD(&srv_ni->sni_rqbds); - srv_ni->sni_nrqbds = 0; - atomic_set(&srv_ni->sni_nrqbds_receiving, 0); - } - - /* Now allocate the event queue and request buffers, assuming all - * interfaces require the same level of buffering. */ - for (i = 0; i < ptlrpc_ninterfaces; i++) { - srv_ni = &service->srv_interfaces[i]; - CDEBUG (D_NET, "%s: initialising interface %s\n", name, - srv_ni->sni_ni->pni_name); - - rc = PtlEQAlloc(srv_ni->sni_ni->pni_ni_h, nevents, - request_in_callback, &(srv_ni->sni_eq_h)); - if (rc != PTL_OK) { - CERROR("%s.%d: PtlEQAlloc on %s failed: %d\n", - name, i, srv_ni->sni_ni->pni_name, rc); - GOTO (failed, NULL); - } - - for (j = 0; j < nbufs; j++) { - struct ptlrpc_request_buffer_desc *rqbd; - - OBD_ALLOC(rqbd, sizeof(*rqbd)); - if (rqbd == NULL) { - CERROR ("%s.%d: Can't allocate request " - "descriptor %d on %s\n", - name, i, srv_ni->sni_nrqbds, - srv_ni->sni_ni->pni_name); - GOTO(failed, NULL); - } - - rqbd->rqbd_srv_ni = srv_ni; - 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) { - CERROR ("%s.%d: Can't allocate request " - "buffer %d on %s\n", - name, i, srv_ni->sni_nrqbds, - srv_ni->sni_ni->pni_name); - OBD_FREE(rqbd, sizeof(*rqbd)); - GOTO(failed, NULL); - } - list_add(&rqbd->rqbd_list, &srv_ni->sni_rqbds); - srv_ni->sni_nrqbds++; - - ptlrpc_link_svc_me(rqbd); - } - } - - CDEBUG(D_NET, "%s: Started on %d interfaces, listening on portal %d\n", - service->srv_name, ptlrpc_ninterfaces, service->srv_req_portal); - - 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_srv_ni->sni_service == svc); - LASSERT (rqbd->rqbd_buffer == event->mem_desc.start); - LASSERT (event->offset + event->mlength <= svc->srv_buf_size); - - memset(request, 0, sizeof(*request)); - INIT_LIST_HEAD(&request->rq_list); - 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 " - LPU64"\n", - request->rq_reqlen, svc->srv_req_portal, - event->initiator.nid, request->rq_xid); - goto out; - } - - CDEBUG(D_RPCTRACE, "Handling RPC ni:pid:xid:nid:opc %d:%d:"LPU64":" - LPX64":%d\n", rqbd->rqbd_srv_ni - &svc->srv_interfaces[0], - 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; - request->rq_peer.peer_ni = rqbd->rqbd_srv_ni->sni_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); - reparent_to_init(); -} - -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; - unsigned long flags; - ENTRY; - - lock_kernel(); - ptlrpc_daemonize(); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - sigfillset(¤t->blocked); - recalc_sigpending(); -#else - spin_lock_irqsave(¤t->sigmask_lock, flags); - sigfillset(¤t->blocked); - recalc_sigpending(current); - spin_unlock_irqrestore(¤t->sigmask_lock, flags); -#endif - -#ifdef __arch_um__ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - sprintf(current->comm, "%s|%d", data->name,current->thread.extern_pid); -#endif -#else - strcpy(current->comm, data->name); -#endif - unlock_kernel(); - - 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); - - /* CLONE_VM and CLONE_FILES just avoid a needless copy, because we - * just drop the VM and FILES in ptlrpc_daemonize() right away. - */ - rc = kernel_thread(ptlrpc_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 i; - int rc; - struct ptlrpc_srv_ni *srv_ni; - - 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. - */ - - for (i = 0; i < ptlrpc_ninterfaces; i++) { - srv_ni = &service->srv_interfaces[i]; - CDEBUG (D_NET, "%s: tearing down interface %s\n", - service->srv_name, srv_ni->sni_ni->pni_name); - - while (!list_empty (&srv_ni->sni_rqbds)) { - struct ptlrpc_request_buffer_desc *rqbd = - list_entry (srv_ni->sni_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)); - srv_ni->sni_nrqbds--; - } - - LASSERT (srv_ni->sni_nrqbds == 0); - - if (ptl_is_valid_handle (&srv_ni->sni_eq_h)) { - rc = PtlEQFree(srv_ni->sni_eq_h); - if (rc) - CERROR("%s.%d: PtlEQFree failed on %s: %d\n", - service->srv_name, i, - srv_ni->sni_ni->pni_name, rc); - } - } - - OBD_FREE(service, - offsetof (struct ptlrpc_service, - srv_interfaces[ptlrpc_ninterfaces])); - return 0; -} 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 95c1d06..0000000 --- a/lustre/scripts/lustre +++ /dev/null @@ -1,95 +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 - -# Create /var/lustre directory -# This is used by snmp agent for checking lustre services \ -# status online/offline/online pending/offline pending. - -[ -d ${STATUS_DIR:=/var/lustre} ] || mkdir -p $STATUS_DIR -STATUS=${STATUS_DIR}/sysStatus - -start() { - echo -n "Starting $SERVICE: " - ${LCONF} ${LCONF_START_ARGS} - RETVAL=$? - echo $SERVICE - if [ $RETVAL -eq 0 ]; then - touch $LOCK - echo "online" >$STATUS - else - echo "online pending" >$STATUS - fi -} - -stop() { - echo -n "Shutting down $SERVICE: " - ${LCONF} ${LCONF_STOP_ARGS} - RETVAL=$? - echo $SERVICE - rm -f $LOCK - if [ $RETVAL -eq 0 ]; then - echo "offline" >$STATUS - else - echo "offline pending" >$STATUS - fi -} - -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 6b40c41..0000000 --- a/lustre/scripts/lustre.spec.in +++ /dev/null @@ -1,206 +0,0 @@ -# lustre.spec -%define version HEAD -%define kversion @RELEASE@ -%define linuxdir @LINUX@ -%define portalsdir @PORTALS@ -%define portalslibdir @PORTALSLIB@ -Release: 0302240920chaos - -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 - -%package -n lustre-ldap -Summary: Configures openldap server for LDAP Lustre config database -Group: Configuration -Requires: openldap-servers, openldap-clients, python-ldap, 4Suite - -%description -n lustre-ldap -Configures openldap server for LDAP Lustre config database - - -%package -n liblustre -Summary: Lustre Lib -Group: Development/Kernel - -%description -n liblustre -Lustre lib binary package. - - -%prep -%setup -qn lustre-%{version} -%setup -c -n lustre-%{version}-lib - -%build -rm -rf $RPM_BUILD_ROOT - -# Set an explicit path to our Linux tree, if we can. -cd $RPM_BUILD_DIR/lustre-%{version} -./configure --with-linux='%{linuxdir}' --with-portals='%{portalsdir}' --with-portalslib='%{portalslibdir}' -make -cd $RPM_BUILD_DIR/lustre-%{version}-lib/lustre-%{version} -./configure --with-lib --with-portals='%{portalsdir}' --with-portalslib='%{portalslibdir}' -make - -%install -cd $RPM_BUILD_DIR/lustre-%{version} -make install prefix=$RPM_BUILD_ROOT - -cd $RPM_BUILD_DIR/lustre-%{version}-lib/lustre-%{version} -make install prefix=$RPM_BUILD_ROOT - - -# Create the pristine source directory. -cd $RPM_BUILD_DIR/lustre-%{version} -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} - -# ldap database directory -mkdir -p $RPM_BUILD_ROOT/var/lib/ldap/lustre - -%files -%attr(-, root, root) /usr/sbin/lmc -%attr(-, root, root) /usr/sbin/lctl -%attr(-, root, root) /usr/sbin/lconf -%attr(-, root, root) /usr/sbin/llanalyze -%attr(-, root, root) /usr/sbin/lfind -%attr(-, root, root) /usr/sbin/lstripe -%attr(-, root, root) /usr/sbin/mcreate -%attr(-, root, root) /usr/sbin/mkdirmany -%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/fsfilt_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} - -%files -n liblustre -%attr(-, root, root) /lib/lustre -%attr(-, root, root) /lib/lustre/liblov.a -%attr(-, root, root) /lib/lustre/liblustreclass.a -%attr(-, root, root) /lib/lustre/libptlrpc.a -%attr(-, root, root) /lib/lustre/libobdecho.a -%attr(-, root, root) /lib/lustre/libldlm.a -%attr(-, root, root) /lib/lustre/libosc.a -%attr(-, root, root) /usr/sbin/lctl -%attr(-, root, root) /usr/sbin/lfind -%attr(-, root, root) /usr/sbin/lstripe -%attr(-, root, root) /usr/sbin/obdio -%attr(-, root, root) /usr/sbin/obdbarrier -%attr(-, root, root) /usr/sbin/obdstat -%attr(-, root, root) /usr/sbin/lload -%attr(-, root, root) /usr/sbin/lconf -%attr(-, root, root) /usr/sbin/lmc -%attr(-, root, root) /usr/sbin/llanalyze - - -%files -n lustre-ldap -%attr(-, root, root) /etc/openldap/slapd-lustre.conf -%attr(-, root, root) /etc/openldap/schema/lustre.schema -%attr(-, root, root) /usr/lib/lustre/lustre2ldif.xsl -%attr(-, root, root) /usr/lib/lustre/top.ldif -%dir /var/lib/ldap/lustre -%attr(700, ldap, ldap) /var/lib/ldap/lustre - -%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 - -%post -n lustre-ldap -if ! grep -q slapd-lustre /etc/openldap/slapd.conf; then - echo "include /etc/openldap/slapd-lustre.conf" >> /etc/openldap/slapd.conf -fi - -%postun -n lustre-ldap -slapd=/etc/openldap/slapd.conf -if grep -q slapd-lustre $slapd; then - tmp=/tmp/lustre-ldap.$$ - sed "/slapd-lustre/d" $slapd >> $tmp - cp $tmp $slapd - rm $tmp -fi - -%clean -#rm -rf $RPM_BUILD_ROOT - -# end of file diff --git a/lustre/scripts/maketags.sh b/lustre/scripts/maketags.sh deleted file mode 100755 index 9bd9f87..0000000 --- a/lustre/scripts/maketags.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution -set -vx -rm -f TAGS ; find . -name '*.h' -or -name '*.c' | xargs etags -rm -f ctags; find . -name '*.h' -or -name '*.c' | xargs ctags 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/system-profile.sh b/lustre/scripts/system-profile.sh deleted file mode 100755 index a669339..0000000 --- a/lustre/scripts/system-profile.sh +++ /dev/null @@ -1,233 +0,0 @@ -#!/bin/sh - -# System Profiling Script - -TESTS="oprofile iostat vmstat proc_dump" - -# common parameters -export OUTPUTDIR=/home/op -export KERNELDIR=/usr/src/linux -export LUSTREDIR=/usr/src/lustre -export PORTALSDIR=/usr/src/portals -NAL=toenal - -# Params for OPROFILE -#CTR0_EVENT=CPU_CLK_UNHALTED -CTR0_COUNT=10000 - -# for intel Petium 4 onwards... Also requires Unit Mask -CTR0_EVENT=GLOBAL_POWER_EVENTS -CTR0_UNIT_MASK=0x01 - -# Params for VMSTAT -VM_SAMPLING=1 - -# Params for IOSTAT -IO_SAMPLING=1 - -# Params for PROC DUMP -export PROC_SAMPLING=2 - -#------------------------------------------------------------------- -oprofile_start() { - - echo `date +%T`": oprofile started...." >> $OUTPUTDIR/$HOSTNAME/summary - op_start --ctr0-event=$CTR0_EVENT --ctr0-count=$CTR0_COUNT --ctr0-unit-mask=$CTR0_UNIT_MASK --vmlinux=${KERNELDIR}/vmlinux - mkdir -p ${OUTPUTDIR}/${HOSTNAME}/oprofile/prof_source/{obdclass,obdecho,osc,ptlrpc,extN,obdfilter,ost,mdc,mds4mds,mds4mds_extN,llite,portals,$NAL} - mkdir -p ${OUTPUTDIR}/${HOSTNAME}/oprofile/profiling - -} - -iostat_start() { - echo `date +%T`": iostat started...." >> $OUTPUTDIR/$HOSTNAME/summary - - mkdir ${OUTPUTDIR}/${HOSTNAME}/iostat - - iostat $IO_SAMPLING > $OUTPUTDIR/$HOSTNAME/iostat/iostat.op & - PID=$! - echo $PID > $OUTPUTDIR/$HOSTNAME/tmp/iostat.pid -} - -vmstat_start() { - - echo $OUTPUTDIR; - echo `date +%T`": vmstat started...." >> $OUTPUTDIR/$HOSTNAME/summary - - mkdir ${OUTPUTDIR}/${HOSTNAME}/vmstat - - vmstat $VM_SAMPLING > $OUTPUTDIR/$HOSTNAME/vmstat/vmstat.op & - PID=$! - echo $PID > $OUTPUTDIR/$HOSTNAME/tmp/vmstat.pid -} - -proc_dump_start() { - echo `date +%T`": proc dump started...." >> $OUTPUTDIR/$HOSTNAME/summary - sh -c ' - CTRFILE=/$OUTPUTDIR/$HOSTNAME/tmp/running.$$.pid; - echo $$ > ${CTRFILE}; - while [ -f $CTRFILE ]; do - cat /proc/meminfo >> $OUTPUTDIR/$HOSTNAME/meminfo; - cat /proc/interrupts >> $OUTPUTDIR/$HOSTNAME/interrupts; - cat /proc/net/dev >> $OUTPUTDIR/$HOSTNAME/net-dev; - sleep ${PROC_SAMPLING}; - done; - ' & - CTRFILE=/tmp/running.$!.pid - echo "proc_dump_ctrl $CTRFILE" >> /tmp/prof-ctrl - -} - -oprofile_stop() { - op_dump - op_stop - - echo `date +%T`": oprofile stopped...." >> $OUTPUTDIR/$HOSTNAME/summary - - for i in obdclass obdecho osc ptlrpc extN obdfilter mds ost mdc llite - do - oprofpp -l ${LUSTREDIR}/${i}/${i}.o > ${OUTPUTDIR}/${HOSTNAME}/oprofile/profiling/${i}.prof 2>/dev/null - done - oprofpp -l ${LUSTREDIR}/mds/mds_extN.o > ${OUTPUTDIR}/${HOSTNAME}/oprofile/profiling/mds_extN.prof 2>/dev/null - oprofpp -l ${PORTALSDIR}/linux/oslib/portals.o > ${OUTPUTDIR}/${HOSTNAME}/oprofile/profiling/portals.prof 2>/dev/null - oprofpp -l ${PORTALSDIR}/linux/${NAL}/k${NAL}.o > ${OUTPUTDIR}/${HOSTNAME}/oprofile/profiling/k${NAL}.prof 2>/dev/null - - - for i in obdclass obdecho osc ptlrpc extN obdfilter ost mdc llite - do - op_to_source --source-dir=${LUSTREDIR}/${i}/ --output-dir=${OUTPUTDIR}/${HOSTNAME}/oprofile/prof_source/${i}/ ${LUSTREDIR}/${i}/${i}.o 2>/dev/null - done - - op_to_source --source-dir=${LUSTREDIR}/mds/ --output-dir=${OUTPUTDIR}/${HOSTNAME}/oprofile/prof_source/mds4mds/ ${LUSTREDIR}/mds/mds.o 2>/dev/null - op_to_source --source-dir=${LUSTREDIR}/mds/ --output-dir=${OUTPUTDIR}/${HOSTNAME}/oprofile/prof_source/mds4mds_extN/ ${LUSTREDIR}/mds/mds_extN.o 2>/dev/null - - op_to_source --source-dir=${PORTALSDIR}/linux/oslib/ --output-dir=${OUTPUTDIR}/${HOSTNAME}/oprofile/prof_source/portals ${PORTALSDIR}/linux/oslib/portals.o 2>/dev/null - op_to_source --source-dir=${PORTALSDIR}/linux/${NAL}/ --output-dir=${OUTPUTDIR}/${HOSTNAME}/oprofile/prof_source/${NAL} ${PORTALSDIR}/linux/${NAL}/k${NAL}.o 2>/dev/null - - op_time -l > ${OUTPUTDIR}/${HOSTNAME}/oprofile/globalprofile 2>/dev/null - -} - -iostat_stop() { - echo `date +%T`": iostat stopped...." >> $OUTPUTDIR/$HOSTNAME/summary - - PID=$(cat $OUTPUTDIR/$HOSTNAME/tmp/iostat.pid) - kill $PID -} - -vmstat_stop() { - echo `date +%T`": vmstat stopped...." >> $OUTPUTDIR/$HOSTNAME/summary - - PID=$(cat $OUTPUTDIR/$HOSTNAME/tmp/vmstat.pid) - kill $PID -} - -oprofile_dump() { - op_dump; -} - -proc_dump_stop() { - echo `date +%T`": proc dump stopped...." >> $OUTPUTDIR/$HOSTNAME/summary - CTRFILE=`cat /tmp/prof-ctrl | awk '$1 == "prof_dump_ctrl" {print $2}'` - rm -f $CTRFILE -} -#------------------------------------------------------------------- - -case "$1" in - - start) - - shift; - while [ ${#*} -gt 1 ]; do - case "$1" in - -k) - shift; - KERNELDIR=$1; - ;; - - -l) - shift; - LUSTREDIR=$1; - ;; - -p) - shift; - PORTALSDIR=$1; - ;; - - -o) - shift; - OUTPUTDIR=$1; - ;; - *) - echo unrecognized option $1 - break; - ;; - esac - shift; - done - echo "kerneldir $KERNELDIR" > /tmp/prof-ctrl - echo -e "\nlustredir $LUSTREDIR" >> /tmp/prof-ctrl - echo -e "\nportalsdir $PORTALSDIR" >> /tmp/prof-ctrl - echo -e "\noutputdir $OUTPUTDIR" >> /tmp/prof-ctrl - - if [ -d ${OUTPUTDIR}/${HOSTNAME} ]; then - echo "Output already exists" - echo "Please take backup and remove it" - exit 1 - fi - - mkdir -p ${OUTPUTDIR}/${HOSTNAME} - echo -e "Profiling started on $HOSTNAME" > ${OUTPUTDIR}/${HOSTNAME}/summary - echo -e "\n\nModules Listing on $HOSTNAME" >> ${OUTPUTDIR}/${HOSTNAME}/summary - /sbin/lsmod >> ${OUTPUTDIR}/${HOSTNAME}/summary - echo -e "\n\nKernel : " >> ${OUTPUTDIR}/${HOSTNAME}/summary - uname -a >> ${OUTPUTDIR}/${HOSTNAME}/summary - echo -e "\n\nPCI Devices : " >> ${OUTPUTDIR}/${HOSTNAME}/summary - lspci -t -v >> ${OUTPUTDIR}/${HOSTNAME}/summary - echo -e "\n\nTests carried out " >> ${OUTPUTDIR}/${HOSTNAME}/summary - - mkdir $OUTPUTDIR/$HOSTNAME/tmp - for test in $TESTS; do - ${test}_start; - done - ;; - stop) - - KERNELDIR=`cat /tmp/prof-ctrl | awk '$1 == "kerneldir" {print $2}'` - LUSTREDIR=`cat /tmp/prof-ctrl | awk '$1 == "lustredir" {print $2}'` - PORTALSDIR=`cat /tmp/prof-ctrl | awk '$1 == "portalsdir" {print $2}'` - OUTPUTDIR=`cat /tmp/prof-ctrl | awk '$1 == "outputdir" {print $2}'` - for test in $TESTS; do - ${test}_stop; - done - - rm -rf ${OUTPUTDIR}/$HOSTNAME/tmp - tar -cf ${OUTPUTDIR}/${HOSTNAME}.tar ${OUTPUTDIR}/${HOSTNAME} - echo "Dumped results in ${OUTPUTDIR}/${HOSTNAME}.tar" - ;; - dump) - if "oprofile" in $TESTS; then - oprofile_dump; - fi - ;; - clean) - - OUTPUTDIR=`cat /tmp/prof-ctrl | awk '$1 == "outputdir" {print $2}'` - echo Deleting directory $OUTPUTDIR/$HOSTNAME ... - rm -rf $OUTPUTDIR/$HOSTNAME - echo Deleting file $OUTPUTDIR/${HOSTNAME}.tar ... - rm -rf $OUTPUTDIR/${HOSTNAME}.tar - echo Deleting oprofile samples ... - rm -f /var/lib/oprofile/samples/* - rm -f /tmp/prof-ctrl - ;; - *) - echo $"Usage : $0 {start|stop|dump|clean} [OPTIONS]"; - echo $"OPTIONS :" - echo $" -l lustre_dir" - echo $" -p portals_dir" - echo $" -k kernel_dir" - echo $" -o output_dir" - exit 1 -esac - -exit 0 diff --git a/lustre/scripts/version_tag.pl b/lustre/scripts/version_tag.pl deleted file mode 100644 index 3575b87..0000000 --- a/lustre/scripts/version_tag.pl +++ /dev/null @@ -1,171 +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"; - } -} -chomp(my $cwd = `pwd`); - -# ARGV[0] = srcdir -# ARGV[1] = builddir - -# for get_latest_mtime and get_tag you need to be in srcdir - -if ($ARGV[0]) { - chdir($ARGV[0]); -} -my $tag = get_tag(); -my $mtime = get_latest_mtime(); - -# for get_linuxdir you need to be in builddir - -if ($ARGV[1]) { - chdir($cwd); - chdir($ARGV[1]); -} -my $linuxdir = get_linuxdir(); - -generate_ver($tag, $mtime, $linuxdir); - -exit(0); diff --git a/lustre/tests/.cvsignore b/lustre/tests/.cvsignore deleted file mode 100644 index 7a18486..0000000 --- a/lustre/tests/.cvsignore +++ /dev/null @@ -1,37 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -TAGS -openunlink -testreq -truncate -directio -openme -writeme -mcreate -munlink -mlink -tchmod -toexcl -fsx -test_brw -newfile -openclose -createdestroy -createmany -statmany -mkdirmany -lovstripe -*.xml -stat -setuid -multifstat -checkstat -wantedi -createtest -open_delay -statone diff --git a/lustre/tests/Makefile.am b/lustre/tests/Makefile.am deleted file mode 100644 index 628c46b..0000000 --- a/lustre/tests/Makefile.am +++ /dev/null @@ -1,59 +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 mcreate \ - elan-client.cfg mds.cfg trivial.sh -pkgexampledir = '${exec_prefix}/usr/lib/$(PACKAGE)/examples' -pkgexample_SCRIPTS = llmount.sh llmountcleanup.sh llecho.sh llechocleanup.sh local.sh echo.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 open_delay -noinst_PROGRAMS += munlink tchmod toexcl fsx test_brw openclose createdestroy -noinst_PROGRAMS += stat createmany statmany multifstat createtest mlink -# noinst_PROGRAMS += ldaptest -noinst_PROGRAMS += checkstat wantedi statone -sbin_PROGRAMS = mcreate mkdirmany - -# ldaptest_SOURCES = ldaptest.c -tchmod_SOURCES = tchmod.c -toexcl_SOURCES = toexcl.c -testreq_SOURCES = testreq.c -mcreate_SOURCES = mcreate.c -munlink_SOURCES = munlink.c -mlink_SOURCES = mlink.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 -stat_SOURCES = stat.c -createmany_SOURCES = createmany.c -statmany_SOURCES = statmany.c -statone_SOURCES = statone.c -mkdirmany_SOURCES = mkdirmany.c -multifstat_SOURCES = multifstat.c -checkstat_SOURCES = checkstat.c -wantedi_SOURCES = wantedi.c -createtest_SOURCES = createtest.c -open_delay_SOURCES = open_delay.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-metadata-double.sh b/lustre/tests/acceptance-metadata-double.sh deleted file mode 100644 index f647a55..0000000 --- a/lustre/tests/acceptance-metadata-double.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/bin/sh -set -e - -# -# Runs create.pl and rename.pl on two mountpoints with increasing load, varying -# debug levels. Assumes that the node is already setup with llmount2.sh -# - -SRCDIR="`dirname $0`" -CREATE=$SRCDIR/create.pl - -debug_client_on() -{ - echo -1 > /proc/sys/portals/debug -} - -debug_client_off() -{ - echo 0 > /proc/sys/portals/debug -} - -MNT=${MNT:-/mnt/lustre} - -debug_client_on -echo "create.pl, 2 mounts, 1 thread, 10 ops, debug on" -perl $CREATE -- $MNT 2 10 -echo "create.pl, 2 mounts, 1 thread, 100 ops, debug on" -perl $CREATE --silent -- $MNT 2 100 -echo "create.pl --mcreate=0, 2 mounts, 1 thread, 10 ops, debug on" -perl $CREATE --mcreate=0 -- $MNT 2 10 -echo "create.pl --mcreate=0, 2 mounts, 1 thread, 100 ops, debug on" -perl $CREATE --mcreate=0 --silent -- $MNT 2 100 -echo "rename.pl, 2 mounts, 1 thread, 10 ops, debug on" -perl rename.pl --count=2 $MNT 10 -echo "rename.pl, 2 mounts, 1 thread, 100 ops, debug on" -perl rename.pl --count=2 --silent $MNT 100 - -debug_client_off -echo "create.pl, 2 mounts, 1 thread, 1000 ops, debug off" -perl $CREATE --silent -- $MNT 2 1000 -echo "create.pl --mcreate=0, 2 mounts, 1 thread, 1000 ops, debug off" -perl $CREATE --silent --mcreate=0 -- $MNT 2 1000 -echo "rename.pl, 2 mounts, 1 thread, 1000 ops, debug off" -perl rename.pl --count=2 --silent $MNT 1000 - -debug_client_on -echo "create.pl, 2 mounts, 2 threads, 100 ops, debug on" -perl $CREATE --silent -- $MNT 2 100 & -perl $CREATE --silent -- $MNT 2 100 & -wait -echo "create.pl --mcreate=0, 2 mounts, 2 threads, 100 ops, debug on" -perl $CREATE --silent --mcreate=0 -- $MNT 2 100 & -perl $CREATE --silent --mcreate=0 -- $MNT 2 100 & -wait -echo "rename.pl, 2 mounts, 2 thread, 1000 ops, debug on" -perl rename.pl --count=2 --silent $MNT 1000 & -perl rename.pl --count=2 --silent $MNT 1000 & -wait - -debug_client_off -echo "create.pl, 2 mounts, 2 threads, 2000 ops, debug off" -perl $CREATE --silent -- $MNT 2 2000 & -perl $CREATE --silent -- $MNT 2 2000 & -wait -echo "create.pl --mcreate=0, 2 mounts, 2 threads, 2000 ops, debug off" -perl $CREATE --silent --mcreate=0 -- $MNT 2 2000 & -perl $CREATE --silent --mcreate=0 -- $MNT 2 2000 & -wait -echo "rename.pl, 2 mounts, 2 threads, 2000 ops, debug off" -perl rename.pl --count=2 --silent $MNT 2000 & -perl rename.pl --count=2 --silent $MNT 2000 & -wait - -debug_client_on -echo "create.pl, 2 mounts, 4 threads, 100 ops, debug on" -for i in `seq 1 4`; do - perl $CREATE --silent -- $MNT 2 100 & -done -wait -echo "create.pl --mcreate=0, 2 mounts, 4 threads, 100 ops, debug on" -for i in `seq 1 4`; do - perl $CREATE --silent --mcreate=0 -- $MNT 2 100 & -done -wait -echo "rename.pl, 2 mounts, 4 threads, 2000 ops, debug on" -for i in `seq 1 4`; do - perl rename.pl --count=2 --silent $MNT 2000 & -done -wait - -debug_client_off -echo "create.pl, 2 mounts, 4 threads, 2000 ops, debug off" -for i in `seq 1 4`; do - perl $CREATE --silent -- $MNT 2 2000 & -done -wait -echo "create.pl --mcreate=0, 2 mounts, 4 threads, 2000 ops, debug off" -for i in `seq 1 4`; do - perl $CREATE --silent --mcreate=0 -- $MNT 2 2000 & -done -wait -echo "rename.pl, 2 mounts, 4 threads, 2000 ops, debug off" -for i in `seq 1 4`; do - perl rename.pl --count=2 --silent $MNT 2000 & -done -wait - -debug_client_on -echo "create.pl, 2 mounts, 8 threads, 500 ops, debug on" -for i in `seq 1 8`; do - perl $CREATE --silent -- $MNT 2 500 & -done -wait -echo "create.pl --mcreate=0, 2 mounts, 8 threads, 500 ops, debug on" -for i in `seq 1 8`; do - perl $CREATE --silent --mcreate=0 -- $MNT 2 500 & -done -wait -echo "rename.pl, 2 mounts, 8 threads, 2000 ops, debug on" -for i in `seq 1 8`; do - perl rename.pl --count=2 --silent $MNT 2000 & -done -wait - -debug_client_off -echo "create.pl, 2 mounts, 8 threads, 2000 ops, debug off" -for i in `seq 1 8`; do - perl $CREATE --silent -- $MNT 2 2000 & -done -wait -echo "create.pl --mcreate=0, 2 mounts, 8 threads, 2000 ops, debug off" -for i in `seq 1 8`; do - perl $CREATE --silent --mcreate=0 -- $MNT 2 2000 & -done -wait -echo "rename.pl, 2 mounts, 8 threads, 2000 ops, debug off" -for i in `seq 1 8`; do - perl rename.pl --count=2 --silent $MNT 2000 & -done -wait diff --git a/lustre/tests/acceptance-metadata-single.sh b/lustre/tests/acceptance-metadata-single.sh deleted file mode 100644 index 53774e5..0000000 --- a/lustre/tests/acceptance-metadata-single.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/sh -set -e - -# -# Runs create.pl and rename.pl on a single mountpoint with increasing -# load, varying debug levels -# - -SRCDIR="`dirname $0`" -CREATE=$SRCDIR/create.pl - -debug_client_on() -{ - echo -1 > /proc/sys/portals/debug -} - -debug_client_off() -{ - echo 0 > /proc/sys/portals/debug -} - -MNT=${MNT:-/mnt/lustre} - -debug_client_on -echo "create.pl, 1 mount, 1 thread, 10 ops, debug on" -perl $CREATE -- $MNT -1 10 -echo "create.pl, 1 mount, 1 thread, 100 ops, debug on" -perl $CREATE --silent -- $MNT -1 100 -echo "create.pl --mcreate=0, 1 mount, 1 thread, 10 ops, debug on" -perl $CREATE --mcreate=0 -- $MNT -1 10 -echo "create.pl --mcreate=0, 1 mount, 1 thread, 100 ops, debug on" -perl $CREATE --mcreate=0 --silent -- $MNT -1 100 -echo "rename.pl, 1 mount, 1 thread, 10 ops, debug on" -perl rename.pl $MNT 10 -echo "rename.pl, 1 mount, 1 thread, 100 ops, debug on" -perl rename.pl --silent $MNT 100 - -debug_client_off -echo "create.pl, 1 mount, 1 thread, 1000 ops, debug off" -perl $CREATE --silent -- $MNT -1 1000 -echo "create.pl --mcreate=0, 1 mount, 1 thread, 1000 ops, debug off" -perl $CREATE --silent --mcreate=0 -- $MNT -1 1000 -echo "rename.pl, 1 mount, 1 thread, 1000 ops, debug off" -perl rename.pl --silent $MNT 1000 - -debug_client_on -echo "create.pl, 1 mount, 2 threads, 100 ops, debug on" -perl $CREATE --silent -- $MNT -1 100 & -perl $CREATE --silent -- $MNT -1 100 & -wait -echo "create.pl --mcreate=0, 1 mount, 2 threads, 100 ops, debug on" -perl $CREATE --silent --mcreate=0 -- $MNT -1 100 & -perl $CREATE --silent --mcreate=0 -- $MNT -1 100 & -wait -echo "rename.pl, 1 mount, 2 thread, 1000 ops, debug on" -perl rename.pl --silent $MNT 1000 & -perl rename.pl --silent $MNT 1000 & -wait - -debug_client_off -echo "create.pl, 1 mount, 2 threads, 2000 ops, debug off" -perl $CREATE --silent -- $MNT -1 2000 & -perl $CREATE --silent -- $MNT -1 2000 & -wait -echo "create.pl --mcreate=0, 1 mount, 2 threads, 2000 ops, debug off" -perl $CREATE --silent --mcreate=0 -- $MNT -1 2000 & -perl $CREATE --silent --mcreate=0 -- $MNT -1 2000 & -wait -echo "rename.pl, 1 mount, 2 threads, 2000 ops, debug off" -perl rename.pl --silent $MNT 2000 & -perl rename.pl --silent $MNT 2000 & -wait - -debug_client_on -echo "create.pl, 1 mount, 4 threads, 100 ops, debug on" -for i in `seq 1 4`; do - perl $CREATE --silent -- $MNT -1 100 & -done -wait -echo "create.pl --mcreate=0, 1 mount, 4 threads, 100 ops, debug on" -for i in `seq 1 4`; do - perl $CREATE --silent --mcreate=0 -- $MNT -1 100 & -done -wait -echo "rename.pl, 1 mount, 4 threads, 2000 ops, debug on" -for i in `seq 1 4`; do - perl rename.pl --silent $MNT 2000 & -done -wait - -debug_client_off -echo "create.pl, 1 mount, 4 threads, 2000 ops, debug off" -for i in `seq 1 4`; do - perl $CREATE --silent -- $MNT -1 2000 & -done -wait -echo "create.pl --mcreate=0, 1 mount, 4 threads, 2000 ops, debug off" -for i in `seq 1 4`; do - perl $CREATE --silent --mcreate=0 -- $MNT -1 2000 & -done -wait -echo "rename.pl, 1 mount, 4 threads, 2000 ops, debug off" -for i in `seq 1 4`; do - perl rename.pl --silent $MNT 2000 & -done -wait - -debug_client_on -echo "create.pl, 1 mount, 8 threads, 500 ops, debug on" -for i in `seq 1 8`; do - perl $CREATE --silent -- $MNT -1 500 & -done -wait -echo "create.pl --mcreate=0, 1 mount, 8 threads, 500 ops, debug on" -for i in `seq 1 8`; do - perl $CREATE --silent --mcreate=0 -- $MNT -1 500 & -done -wait -echo "rename.pl, 1 mount, 8 threads, 2000 ops, debug on" -for i in `seq 1 8`; do - perl rename.pl --silent $MNT 2000 & -done -wait - -debug_client_off -echo "create.pl, 1 mount, 8 threads, 2000 ops, debug off" -for i in `seq 1 8`; do - perl $CREATE --silent -- $MNT -1 2000 & -done -wait -echo "create.pl --mcreate=0, 1 mount, 8 threads, 2000 ops, debug off" -for i in `seq 1 8`; do - perl $CREATE --silent --mcreate=0 -- $MNT -1 2000 & -done -wait -echo "rename.pl, 1 mount, 8 threads, 2000 ops, debug off" -for i in `seq 1 8`; do - perl rename.pl --silent $MNT 2000 & -done -wait -sh rundbench 1 -sh rundbench 2 -sh rundbench 4 -sh rundbench 8 -sh rundbench 16 -sh rundbench 32 diff --git a/lustre/tests/acceptance-small.sh b/lustre/tests/acceptance-small.sh deleted file mode 100755 index bee6588..0000000 --- a/lustre/tests/acceptance-small.sh +++ /dev/null @@ -1,111 +0,0 @@ -#!/bin/sh -# script which _must_ complete successfully (at minimum) before checkins to -# the CVS HEAD are allowed. -set -vxe - -[ "$CONFIGS" -a -z "$SANITYN" ] && SANITYN=no -[ "$CONFIGS" ] || CONFIGS="local lov" -[ "$MAX_THREADS" ] || MAX_THREADS=50 -if [ -z "$THREADS" ]; then - KB=`awk '/MemTotal:/ { print $2 }' /proc/meminfo` - THREADS=`expr $KB / 16384` - [ $THREADS -gt $MAX_THREADS ] && THREADS=$MAX_THREADS -fi -[ "$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 - - [ "$SANITY" != "no" ] && sh sanity.sh - [ "$SANITY" != "no" ] && START=" " CLEAN=" " sh sanity.sh - - if [ "$DBENCH" != "no" ]; then - mount | grep $MNT || sh llmount.sh - SPACE=`df $MNT | tail -1 | awk '{ print $4 }'` - DB_THREADS=`expr $SPACE / 50000` - [ $THREADS -lt $DB_THREADS ] && DB_THREADS=$THREADS - - $DEBUG_OFF - sh rundbench 1 - sh llmountcleanup.sh - sh llrmount.sh - if [ $DB_THREADS -gt 1 ]; then - $DEBUG_OFF - sh rundbench $DB_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 - mount | grep $MNT || sh llmount.sh - $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 - mount | grep $MNT || sh llmount.sh - $DEBUG_OFF - iozone $IOZONE_OPTS $IOZONE_FILE - sh llmountcleanup.sh - sh llrmount.sh - fi - if [ "$IOZONE_DIR" != "no" ]; then - mount | grep $MNT || sh llmount.sh - SPACE=`df $MNT | tail -1 | awk '{ print $4 }'` - IOZ_THREADS=`expr $SPACE / $SIZE` - [ $THREADS -lt $IOZ_THREADS ] && IOZ_THREADS=$THREADS - - $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 [ "$IOZ_THREADS" -gt 1 -a "$IOZVER" -ge 3145 ]; then - $DEBUG_OFF - THREAD=1 - IOZONE_FILE="-F " - while [ $THREAD -le $IOZ_THREADS ]; do - IOZONE_FILE="$IOZONE_FILE $MNT/iozone.$THREAD" - THREAD=`expr $THREAD + 1` - done - iozone -I $IOZONE_OPTS -t $IOZ_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 - mount | grep $MNT || sh llmount.sh - $DEBUG_OFF - ./fsx -W -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 - -if [ "$SANITYN" != "no" ]; then - export NAME=mount2 - mount | grep $MNT || sh llmount.sh - sh sanityN.sh - mount | grep $MNT && sh llmountcleanup.sh -fi diff --git a/lustre/tests/ba-echo.sh b/lustre/tests/ba-echo.sh deleted file mode 100644 index 6d7b7f4..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=${OST:-ba-ost-1} -CLIENT=client - -UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt} - -h2tcp () { - echo "${1}" -} -BATCH=/tmp/lmc-batch.$$ -save_cmd() { - echo "$@" >> $BATCH -} - -[ -f $config ] && rm $config - -# Client node -${LMC} --add net --node $CLIENT --tcpbuf $TCPBUF --nid '*' --nettype tcp - -OST_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST` -[ "$OST_UUID" ] && OST_UUID="--ostuuid=$OST_UUID" || echo "$OST: no UUID" - -# server node -${LMC} --add net --node $OST --tcpbuf $TCPBUF --nid $OST --nettype tcp -${LMC} --add ost --node $OST --ost ost1 --obdtype=obdecho $OST_UUID - -# osc on client -${LMC} --add echo_client --node $CLIENT --ost ost1 - -$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 ac05660..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} - -h2tcp () { - echo "${1}" -} -BATCH=/tmp/lmc-batch.$$ -save_cmd() { - echo "$@" >> $BATCH -} - -[ -f $config ] && rm $config - -# MDS/client node -${LMC} --add net --node $MDS --tcpbuf $TCPBUF --nid $MDS --nettype tcp -${LMC} --add mds --node $MDS --mds mds1 --dev /tmp/mds1 --size 50000 - -OST_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST` -[ "$OST_UUID" ] && OST_UUID="--ostuuid $OST_UUID" || echo "$OST: no UUID" - -# server node -${LMC} --add net --node $OST --tcpbuf $TCPBUF --nid $OST --nettype tcp -${LMC} --add ost --node $OST --ost ost1 $OST_UUID --dev bluearc - -# mount point on the MDS/client -${LMC} --add mtpt --node $MDS --path /mnt/lustre --mds mds1 --lov ost1 - -# other clients -${LMC} --add net --node client --tcpbuf $TCPBUF --nid '*' --nettype tcp -${LMC} --add mtpt --node client --path /mnt/lustre --mds mds1 --lov ost1 - -$LMC_REAL --batch $BATCH -rm -f $BATCH diff --git a/lustre/tests/busy.sh b/lustre/tests/busy.sh deleted file mode 100644 index 2f90986..0000000 --- a/lustre/tests/busy.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - - mkdir /mnt/lustre/d22 - mkdir /mnt/lustre/d22/etc - ./mcreate /mnt/lustre/d22/etc/foo - ls -ld /mnt/lustre/etc - ls -ld /mnt/lustre/d22/etc diff --git a/lustre/tests/checkstat.c b/lustre/tests/checkstat.c deleted file mode 100644 index f09fde9..0000000 --- a/lustre/tests/checkstat.c +++ /dev/null @@ -1,314 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void -usage (char *argv0, int help) -{ - char *progname = strrchr(argv0, '/'); - - if (progname == NULL) - progname = argv0; - - fprintf (help ? stdout : stderr, - "Usage: %s [flags] file[s]\n", - progname); - - if (!help) - { - fprintf (stderr, " or try '-h' for help\n"); - exit (1); - } - - printf ("Check given files have...\n"); - printf (" -p permission file must have required permissions\n"); - printf (" -t dir|file|link file must be of the specified type\n"); - printf (" -l link_name file must be a link to the given name\n"); - printf (" -s size file must have the given size\n"); - printf (" -u user file must be owned by given user\n"); - printf (" -g group file must be owned by given group\n"); - printf (" -f follow symlinks\n"); - printf (" -a file must be absent\n"); - printf (" -v increase verbosity\n"); - printf (" -h print help\n"); - printf (" Exit status is 0 on success, 1 on failure\n"); -} - -int -main (int argc, char **argv) -{ - int c; - struct stat64 buf; - int perms = -1; - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; - char *type = NULL; - long absent = 0; - char *checklink = NULL; - int verbose = 0; - long long size = -1; - int follow = 0; - char *term; - - while ((c = getopt (argc, argv, "p:t:l:s:u:g:avfh")) != -1) - switch (c) - { - case 'p': - perms = (int)strtol (optarg, &term, 0); - if (term == optarg) - { - fprintf (stderr, "Can't parse permission %s\n", optarg); - return (1); - } - break; - - case 'l': - checklink = optarg; - break; - - case 's': - size = strtoll (optarg, &term, 0); - if (term == optarg) - { - fprintf (stderr, "Can't parse size %s\n", optarg); - return (1); - } - break; - - case 'u': - if (*optarg == '#') - { - uid = (uid_t)strtol (optarg + 1, &term, 0); - if (term == optarg + 1) - { - fprintf (stderr, "Can't parse numeric uid %s\n", optarg); - return (1); - } - } else { - struct passwd *pw = getpwnam (optarg); - - if (pw == NULL) - { - fprintf (stderr, "Can't find user %s\n", optarg); - return (1); - } - uid = pw->pw_uid; - } - break; - - case 'g': - if (*optarg == '#') - { - gid = (gid_t)strtol (optarg + 1, &term, 0); - if (term == optarg + 1) - { - fprintf (stderr, "Can't parse numeric gid %s\n", optarg); - return (1); - } - } else { - struct group *gr = getgrnam (optarg); - - if (gr == NULL) - { - fprintf (stderr, "Can't find group %s\n", optarg); - return (1); - } - uid = gr->gr_gid; - } - break; - - case 't': - type = optarg; - break; - - case 'a': - absent = 1; - break; - - case 'v': - verbose++; - break; - - case 'f': - follow++; - break; - - case 'h': - usage (argv[0], 1); - return (0); - - default: - usage (argv[0], 0); - } - - if (optind == argc) - usage (argv[0], 0); - - do - { - char *fname = argv[optind]; - int rc = follow ? stat64 (fname, &buf) : lstat64 (fname, &buf); - - if (rc != 0) - { - if (!(absent && errno == ENOENT)) - { - if (verbose) - printf ("Can't %sstat %s: %s\n", - follow ? "" : "l", - fname, strerror (errno)); - return (1); - } - - if (verbose) - printf ("%s: absent OK\n", fname); - continue; - } - - if (absent) - { - if (verbose) - printf ("%s exists\n", fname); - return (1); - } - - if (type != NULL) - { - if (!strcmp (type, "d") || - !strcmp (type, "dir")) - { - if (!S_ISDIR (buf.st_mode)) - { - if (verbose) - printf ("%s is not a directory\n", - fname); - return (1); - } - } - else if (!strcmp (type, "f") || - !strcmp (type, "file")) - { - if (!S_ISREG (buf.st_mode)) - { - if (verbose) - printf ("%s is not a regular file\n", - fname); - return (1); - } - } - else if (!strcmp (type, "l") || - !strcmp (type, "link")) - { - if (!S_ISLNK (buf.st_mode)) - { - if (verbose) - printf ("%s is not a link\n", - fname); - return (1); - } - } - else - { - fprintf (stderr, "Can't parse file type %s\n", type); - return (1); - } - - if (verbose) - printf ("%s has type %s OK\n", fname, type); - } - - if (perms != -1) - { - if ((buf.st_mode & ~S_IFMT) != perms) - { - if (verbose) - printf ("%s has perms 0%o, not 0%o\n", - fname, (buf.st_mode & ~S_IFMT), perms); - return (1); - } - - if (verbose) - printf ("%s has perms 0%o OK\n", - fname, perms); - } - - if (size != -1) - { - if (buf.st_size != size) - { - if (verbose) - printf ("%s has size %Ld, not %Ld\n", - fname, (long long)buf.st_size, size); - return (1); - } - - if (verbose) - printf ("%s has size %Ld OK\n", fname, size); - } - - if (checklink != NULL) - { - static char lname[4<<10]; - - rc = readlink (fname, lname, sizeof (lname) - 1); - - if (rc < 0) - { - if (verbose) - printf ("%s: can't read link: %s\n", - fname, strerror (errno)); - return (1); - } - - lname[rc] = 0; - if (strcmp (checklink, lname)) - { - if (verbose) - printf ("%s is a link to %s and not %s\n", - fname, lname, checklink); - return (1); - } - - if (verbose) - printf ("%s links to %s OK\n", fname, checklink); - } - - if (uid != (uid_t)-1) - { - if (buf.st_uid != uid) - { - if (verbose) - printf ("%s is owned by user #%ld and not #%ld\n", - fname, (long)buf.st_uid, (long)uid); - return (1); - } - - if (verbose) - printf ("%s is owned by user #%ld OK\n", - fname, (long)uid); - } - - if (gid != (gid_t)-1) - { - if (buf.st_gid != gid) - { - if (verbose) - printf ("%s is owned by group #%ld and not #%ld\n", - fname, (long)buf.st_gid, (long)gid); - return (1); - } - - if (verbose) - printf ("%s is owned by group #%ld OK\n", - fname, (long)gid); - } - } while (++optind < argc); - - return (0); -} diff --git a/lustre/tests/client-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/cobd.sh b/lustre/tests/cobd.sh deleted file mode 100755 index 3f6521a..0000000 --- a/lustre/tests/cobd.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - - -config=${1:-$(basename $0 .sh)}.xml - -LMC=${LMC:-../utils/lmc -m $config} -TMP=${TMP:-/tmp} - -MDSDEV=$TMP/mds1 -MDSSIZE=50000 - -OSTDEV=$TMP/ost1 -OSTSIZE=200000 - -kver=`uname -r | cut -d "." -f 1,2` - -case $kver in - 2.4) FSTYPE="--fstype=extN" ;; - 2.5) FSTYPE="--fstype=ext3" ;; - *) echo "Kernel version $kver not supported" - exit 1 - ;; -esac - -rm -f $config -# create nodes -${LMC} --add node --node localhost || exit 10 -${LMC} --add net --node localhost --nid localhost --nettype tcp || exit 11 - -# configure mds server -${LMC} --add mds --node localhost --mds mds1 --dev $MDSDEV --size $MDSSIZE || exit 20 - -# configure ost -${LMC} --add ost --node localhost --obd obd1 --obdtype obdecho || exit 30 -# configure ost -${LMC} --add ost --node localhost --obd obd2 --obdtype obdecho || exit 30 - -${LMC} --add cobd --node localhost --real_obd obd1 --cache_obd obd2 - -# create client config -# ${LMC} -m $config --add mtpt --node localhost --path /mnt/lustre --mds mds1 --obd obd1 || exit 40 diff --git a/lustre/tests/common.sh b/lustre/tests/common.sh deleted file mode 100644 index 6a4429e..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/obdclass/fsfilt_ext2.o || exit -1 - #do_insmod $LUSTRE/obdclass/fsfilt_ext3.o || exit -1 - do_insmod $LUSTRE/obdclass/fsfilt_extN.o || \ - echo "info: can't load fsfilt_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 fsfilt_extN - do_rmmod fsfilt_ext3 - do_rmmod fsfilt_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/compile.sh b/lustre/tests/compile.sh deleted file mode 100644 index 13c142e..0000000 --- a/lustre/tests/compile.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -set -evx - -MNT=${MNT:-/mnt/lustre} -DIR=${DIR:-$MNT} -SRC=${SRC:-`dirname $0`/../..} -while date; do - for i in portals lustre; do - TGT=$DIR/$i - [ -d $TGT ] || cp -av $SRC/$i/ $TGT - make -C $TGT clean - make -C $TGT -j2 - make -C $TGT clean - done -done diff --git a/lustre/tests/create.pl b/lustre/tests/create.pl deleted file mode 100644 index 6156869..0000000 --- a/lustre/tests/create.pl +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/perl -use Getopt::Long; - -my $silent = 0; -my $mcreate = 1; # should we use mcreate or open? -my $files = 5; - -GetOptions("silent!" => \$silent, - "mcreate=i" => \$mcreate, - "files=i" => \$files); - -my $mtpt = shift || usage(); -my $mount_count = shift || usage(); -my $i = shift || usage(); -my $count = $i; - -sub usage () { - print "Usage: $0 [--silent] [--mcreate=n] [--files=n] \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; - } - if (($count - $i) % 100 == 0) { - print STDERR ($count - $i) . " operations [" . $$ . "]\n"; - } -} - -my $which = ""; -if ($mount_count > 0) { - $which = int(rand() * $mount_count) + 1; -} -for ($d = 0; $d < $files; $d++) { - unlink("$mtpt$which/$d"); -} - -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 8399824..0000000 --- a/lustre/tests/createmany.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void usage(char *prog) -{ - printf("usage: %s {-o|-m} filenamefmt count\n", prog); - printf(" %s {-o|-m} filenamefmt -seconds\n", prog); - printf(" %s {-o|-m} filenamefmt start count\n", prog); -} - -int main(int argc, char ** argv) -{ - int i, rc = 0, do_open; - char format[4096], *fmt; - char filename[4096]; - long start, last, end; - long begin = 0, count; - - if (argc < 4 || argc > 5) { - usage(argv[0]); - return 1; - } - - if (strcmp(argv[1], "-o") == 0) { - do_open = 1; - } else if (strcmp(argv[1], "-m") == 0) { - do_open = 0; - } else { - usage(argv[0]); - return 1; - } - - if (strlen(argv[2]) > 4080) { - printf("name too long\n"); - return 1; - } - - start = last = time(0); - - if (argc == 4) { - end = strtol(argv[3], NULL, 0); - if (end > 0) { - count = end; - end = -1UL >> 1; - } else { - end = start - end; - count = -1UL >> 1; - } - } else { - end = -1UL >> 1; - begin = strtol(argv[3], NULL, 0); - count = strtol(argv[4], NULL, 0); - } - - if (strchr(argv[2], '%')) - fmt = argv[2]; - else { - sprintf(format, "%s%%d", argv[2]); - fmt = format; - } - for (i = 0; i < count && time(0) < end; i++, begin++) { - sprintf(filename, fmt, begin); - if (do_open) { - int fd = open(filename, O_CREAT|O_RDWR, 0644); - if (fd < 0) { - printf("open(%s) error: %s\n", filename, - strerror(errno)); - rc = errno; - break; - } - close(fd); - } else { - rc = mknod(filename, S_IFREG| 0444, 0); - if (rc) { - printf("mknod(%s) error: %s\n", - filename, strerror(errno)); - rc = errno; - break; - } - } - if ((i % 10000) == 0) { - printf(" - created %d (time %ld ; total %ld ; last %ld)\n", - i, time(0), time(0) - start, time(0) - last); - last = time(0); - } - } - printf("total: %d creates in %ld seconds: %f creates/second\n", i, - time(0) - start, ((float)i / (time(0) - start))); - - return rc; -} diff --git a/lustre/tests/createtest.c b/lustre/tests/createtest.c deleted file mode 100644 index 5404f13..0000000 --- a/lustre/tests/createtest.c +++ /dev/null @@ -1,142 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef S_SHIFT -#define S_SHIFT 12 -#endif - -int usage(char *prog) -{ - fprintf(stderr, "usage: %s \n", prog); - exit(1); -} - -int main(int argc, char *argv[]) -{ - char name[4096]; - int i; - - if (argc != 2) - usage(argv[0]); - - umask(0); - for (i = 0; i <= S_IFMT; i += (1 << S_SHIFT)) { - struct stat st; - int mode = i | 0644; - int rc; - - sprintf(name, "%s-mknod%06o", argv[1], mode); - rc = mknod(name, mode, 0x1234); - switch (i) { - case 0: - mode |= S_IFREG; - case S_IFREG: - case S_IFCHR: case S_IFBLK: - if (rc < 0 && getuid() != 0) - continue; - case S_IFSOCK: case S_IFIFO: - if (rc < 0) { - fprintf(stderr, "%s: ERROR mknod %s: %s\n", - argv[0], name, strerror(errno)); - exit(10); - } - rc = stat(name, &st); - if (rc < 0) { - fprintf(stderr, "%s: ERROR stat %s: %s", - argv[0], name, strerror(errno)); - exit(11); - } - if (st.st_mode != mode) { - fprintf(stderr, "%s: ERROR mode %s: %o != %o", - argv[0], name, st.st_mode, mode); - exit(12); - } - rc = unlink(name); - if (rc < 0) { - fprintf(stderr, "%s: ERROR unlink %s: %s", - argv[0], name, strerror(errno)); - exit(13); - } - break; - default: - if (rc == 0) { - fprintf(stderr, "%s: ERROR: %s created\n", - argv[0], name); - exit(14); - } - } - } - - for (i = 0; i <= S_IFMT; i += (1 << S_SHIFT)) { - struct stat st; - int mode; - int fd; - int rc; - - mode = i | 0644; - sprintf(name, "%s-creat%06o", argv[1], mode); - fd = open(name, O_CREAT|O_RDONLY, mode); - if (fd < 0) { - fprintf(stderr, "%s: ERROR creat %s: %s\n", - argv[0], name, strerror(errno)); - exit(21); - } - close(fd); - rc = stat(name, &st); - if (rc < 0) { - fprintf(stderr, "%s: ERROR stat %s: %s", - argv[0], name, strerror(errno)); - exit(11); - } - if ((st.st_mode & S_IFMT) != S_IFREG) { - fprintf(stderr, "%s: ERROR mode %s: %o != %o", - argv[0], name, st.st_mode & S_IFMT, S_IFREG); - exit(12); - } - rc = unlink(name); - if (rc < 0) { - fprintf(stderr, "%s: ERROR unlink %s: %s\n", - argv[0], name, strerror(errno)); - exit(20); - } - } - - for (i = 0; i <= S_IFMT; i += (1 << S_SHIFT)) { - struct stat st; - int rc; - - sprintf(name, "%s-mkdir%06o", argv[1], i | 0644); - rc = mkdir(name, i | 0664); - if (rc < 0) { - fprintf(stderr, "%s: ERROR mkdir %s: %s\n", - argv[0], name, strerror(errno)); - exit(30); - } - rc = stat(name, &st); - if (rc < 0) { - fprintf(stderr, "%s: ERROR stat %s: %s", - argv[0], name, strerror(errno)); - exit(11); - } - if ((st.st_mode & S_IFMT) != S_IFDIR) { - fprintf(stderr, "%s: ERROR mode %s: %o != %o", - argv[0], name, st.st_mode & S_IFMT, S_IFDIR); - exit(12); - } - rc = rmdir(name); - if (rc < 0) { - fprintf(stderr, "%s: ERROR rmdir %s: %s\n", - argv[0], name, strerror(errno)); - exit(31); - } - } - - printf("%s: SUCCESS\n", argv[0]); - return 0; -} diff --git a/lustre/tests/directio.c b/lustre/tests/directio.c deleted file mode 100644 index 3299011..0000000 --- a/lustre/tests/directio.c +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#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 - -int main(int argc, char **argv) -{ - int fd; - char *buf; - int blocks; - struct stat st; - int rc; - - if (argc != 3) { - printf("Usage: %s file nr_blocks\n", argv[0]); - return 1; - } - - blocks = strtoul(argv[2], 0, 0); - fd = open(argv[1], O_DIRECT | O_RDWR | O_CREAT, 0644); - if (fd == -1) { - printf("Cannot open %s: %s\n", argv[1], strerror(errno)); - return 1; - } - - if (fstat(fd, &st) < 0) { - printf("Cannot stat %s: %s\n", argv[1], strerror(errno)); - return 1; - } - - printf("directio on %s for %dx%lu blocks \n", argv[1], blocks, - st.st_blksize); - - buf = mmap(0, blocks * st.st_blksize, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANON, 0, 0); - if (!buf) { - printf("No memory %s\n", strerror(errno)); - return 1; - } - - rc = write(fd, buf, blocks * st.st_blksize); - if (rc != blocks * st.st_blksize) { - printf("Write 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 = read(fd, buf, blocks * st.st_blksize); - if (rc != blocks * st.st_blksize) { - printf("Read error: %s (rc = %d)\n", strerror(errno), rc); - return 1; - } - - return 0; -} diff --git a/lustre/tests/echo.sh b/lustre/tests/echo.sh deleted file mode 100755 index 99e026f..0000000 --- a/lustre/tests/echo.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -LOV=${LOV:-0} -while [ "$1" ]; do - case $1 in - --lov) LOV="1" ;; - *) [ -z $config ] && config=$1 || OPTS="$OPTS $1" ;; - esac - shift -done - -config=${config:-$(basename $0 .sh).xml} -LMC=${LMC:-../utils/lmc -m $config} -TMP=${TMP:-/tmp} - -SERVER=${SERVER:-localhost} -CLIENT=${CLIENT:-localhost} -NET=${NET:-tcp} - -# FIXME: make LMC not require MDS for obdecho LOV -MDSDEV=${MDSDEV:-$TMP/mds1} -MDSSIZE=10000 - -STRIPE_BYTES=65536 -STRIPES_PER_OBJ=2 # 0 means stripe over all OSTs - -rm -f $config -# create nodes -$LMC --add node --node $SERVER || exit 1 -$LMC --add net --node $SERVER --nid $SERVER --nettype $NET || exit 2 - -if (($LOV)); then - $LMC --add mds --node $SERVER --mds mds1 --dev $MDSDEV --size $MDSSIZE || exit 10 - $LMC --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 || exit 11 - $LMC --add ost --node $SERVER --lov lov1 --osdtype=obdecho || exit 12 - $LMC --add ost --node $SERVER --lov lov1 --osdtype=obdecho || exit 13 - OBD_NAME=lov1 -else - $LMC --add ost --ost obd1 --node $SERVER --osdtype=obdecho || exit 12 - OBD_NAME=obd1 -fi - -if [ "$SERVER" != "$CLIENT" ]; then - $LMC --add node --node $CLIENT || exit 1 - $LMC --add net --node $CLIENT --nid $CLIENT --nettype $NET || exit 2 -fi - -$LMC --add echo_client --node $CLIENT --ost ${OBD_NAME} || exit 3 - 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; - - -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; - 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: %lu.%06lu ", opnum, - lp->tv.tv_sec, lp->tv.tv_usec); - - switch (lp->operation) { - case OP_MAPREAD: - prt("MAPREAD 0x%x thru 0x%x (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 (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 0x%x thru 0x%x (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 0x%x thru 0x%x (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_CLOSEOPEN: - prt("CLOSE/OPEN"); - break; - case OP_SKIPPED: - prt("SKIPPED (no operation)"); - break; - default: - prt("BOGUS LOG ENTRY (operation code = %d)!", - lp->operation); - } - 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("%06lu %lu.%06lu read %#08x thru %#08x\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 (!quiet && (debug > 1 && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend))))) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu read done\n", t.tv_sec, t.tv_usec); - } - 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("%06lu %lu.%06lu mapread %#08x thru %#08x\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); - } - if (!quiet && (debug > 1 && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend))))) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu mmap done\n", t.tv_sec, t.tv_usec); - } - memcpy(temp_buf, p + pg_offset, size); - if (!quiet && (debug > 1 && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend))))) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu memcpy done\n", t.tv_sec, t.tv_usec); - } - if (munmap(p, map_size) != 0) { - prterr("domapread: munmap"); - report_failure(191); - } - if (!quiet && (debug > 1 && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend))))) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu munmap done\n", t.tv_sec, t.tv_usec); - } - - 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("%06lu %lu.%06lu write %#08x thru %#08x\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 (!quiet && (debug > 1 && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend))))) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu write done\n", t.tv_sec, t.tv_usec); - } - 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("%06lu %lu.%06lu mapwrite %#08x thru %#08x\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); - } - if (!quiet && (debug > 1 && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend))))) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu truncate done\n", t.tv_sec, t.tv_usec); - } - } - 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); - } - if (!quiet && (debug > 1 && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend))))) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu mmap done\n", t.tv_sec, t.tv_usec); - } - memcpy(p + pg_offset, good_buf + offset, size); - if (!quiet && (debug > 1 && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend))))) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu memcpy done\n", t.tv_sec, t.tv_usec); - } - if (msync(p, map_size, 0) != 0) { - prterr("domapwrite: msync"); - report_failure(203); - } - if (!quiet && (debug > 1 && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend))))) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu msync done\n", t.tv_sec, t.tv_usec); - } - if (munmap(p, map_size) != 0) { - prterr("domapwrite: munmap"); - report_failure(204); - } - if (!quiet && (debug > 1 && - (monitorstart == -1 || - (offset + size > monitorstart && - (monitorend == -1 || offset <= monitorend))))) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu munmap done\n", t.tv_sec, t.tv_usec); - } -} - - -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("%06lu %lu.%06lu trunc from %#08x to %#08x\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); - } - if (!quiet && debug > 1) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu trunc done\n", t.tv_sec, t.tv_usec); - } -} - - -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; - - gettimeofday(&t, NULL); - log4(OP_CLOSEOPEN, file_size, (unsigned)file_size, 0, &t); - - if (debug) - prt("%06lu %lu.%06lu close/open\n", testcalls, t.tv_sec, - t.tv_usec); - if (close(fd)) { - prterr("docloseopen: close"); - report_failure(180); - } - if (!quiet && debug > 1) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu close done\n", t.tv_sec, t.tv_usec); - } - fd = open(fname, O_RDWR, 0); - if (fd < 0) { - prterr("docloseopen: open"); - report_failure(181); - } - if (!quiet && debug > 1) { - gettimeofday(&t, NULL); - prt(" %lu.%06lu open done\n", t.tv_sec, t.tv_usec); - } -} - - -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 (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 (closeprob && (rv >> 3) < (1 << 28) / closeprob) - 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 [-d -d = more debugging]\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++; - 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 b8d234b..0000000 --- a/lustre/tests/leak_finder.pl +++ /dev/null @@ -1,69 +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; - - # we can't dump the log after portals has exited, so skip "leaks" - # from memory freed in the portals module unloading. - if ($func eq 'portals_handle_init') { - next; - } - 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/lkcdmap b/lustre/tests/lkcdmap deleted file mode 100755 index 38e79c8..0000000 --- a/lustre/tests/lkcdmap +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -TMP=${TMP:-/tmp} -LCMD=$TMP/lkcd-cmds-`hostname` -echo "Storing LKCD module info in $LCMD" -cat /tmp/ogdb-`hostname` | while read JUNK M JUNK; do - DIR=`dirname $M` - DIR=`cd $PWD/../$DIR; pwd` - MOD="$DIR/`basename $M`" - MAP=`echo $MOD | sed -e 's/\.o$/.map/'` - MODNAME=`basename $M | sed -e 's/\.o$//'` - - nm $MOD > $MAP - echo namelist -a $MOD | tee -a $LCMD - echo symtab -a $MAP $MODNAME | tee -a $LCMD -done 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 c490856..0000000 --- a/lustre/tests/llmount.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -# suggested boilerplate for test script - -LCONF=${LCONF:-../utils/lconf} -NAME=${NAME:-local} - -config=$NAME.xml -mkconfig=$NAME.sh - -if [ "$PORTALS" ]; then - portals_opt="--portals=$PORTALS" -fi - -if [ "$LUSTRE" ]; then - lustre_opt="--lustre=$LUSTRE" -fi - -if [ "$1" = "-v" ]; then - verbose="-v" -fi - -[ -x $LCONF ] || chmod a+rx $LCONF - -sh $mkconfig $config || exit 1 - -${LCONF} $portals_opt $lustre_opt --reformat --gdb $verbose $config || exit 2 diff --git a/lustre/tests/llmountcleanup.sh b/lustre/tests/llmountcleanup.sh deleted file mode 100755 index cd28d21..0000000 --- a/lustre/tests/llmountcleanup.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh - -LCONF=${LCONF:-../utils/lconf} -NAME=${NAME:-local} -TMP=${TMP:-/tmp} - -config=$NAME.xml -mkconfig=$NAME.sh - -if [ "$PORTALS" ]; then - portals_opt="--portals=$PORTALS" -fi - -if [ "$LUSTRE" ]; then - lustre_opt="--lustre=$LUSTRE" -fi - -if [ ! -f $config ]; then - sh $mkconfig $config || exit 1 -fi - -sync; sleep 2; sync -${LCONF} $portals_opt $lustre_opt --cleanup --dump $TMP/debug $config -rc=$? -BUSY=`dmesg | grep -i destruct` -if [ "$BUSY" ]; then - echo "$BUSY" 1>&2 - mv $TMP/debug $TMP/debug-busy.`date +%s` - exit 255 -fi -LEAK_LUSTRE=`dmesg | tail -20 | grep -v "leaked: 0" | grep leaked` -LEAK_PORTALS=`dmesg | tail -20 | grep "Portals memory leaked"` -if [ "$LEAK_LUSTRE" -o "$LEAK_PORTALS" ]; then - echo "$LEAK_LUSTRE" 1>&2 - echo "$LEAK_PORTALS" 1>&2 - mv $TMP/debug $TMP/debug-leak.`date +%s` - exit 254 -fi - -exit $rc diff --git a/lustre/tests/llrext3.sh b/lustre/tests/llrext3.sh deleted file mode 100755 index c47fe9b..0000000 --- a/lustre/tests/llrext3.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -SRCDIR="`dirname $0`/" -. $SRCDIR/common.sh - -export DEBUG_WAIT=yes -. $SRCDIR/llrsetup.sh $SRCDIR/net-local.cfg $SRCDIR/client-mount.cfg $SRCDIR/mds.cfg $SRCDIR/obdext2.cfg || exit 2 - -debug_client_on -#debug_client_off diff --git a/lustre/tests/llrmount.sh b/lustre/tests/llrmount.sh deleted file mode 100755 index 6531055..0000000 --- a/lustre/tests/llrmount.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -LCONF=${LCONF:-../utils/lconf} -NAME=${NAME:-local} - -config=$NAME.xml -mkconfig=$NAME.sh - -if [ "$PORTALS" ]; then - portals_opt="--portals=$PORTALS" -fi - -if [ "$LUSTRE" ]; then - lustre_opt="--lustre=$LUSTRE" -fi - -if [ ! -f $config -o $mkconfig -nt $config ]; then - sh $mkconfig $config || exit 1 -fi - -${LCONF} $portals_opt $lustre_opt --gdb $config || exit 2 diff --git a/lustre/tests/llrsetup.sh b/lustre/tests/llrsetup.sh deleted file mode 100644 index 44bfcae..0000000 --- a/lustre/tests/llrsetup.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -SRCDIR="`dirname $0`/" -[ -f $SRCDIR/common.sh ] || SRCDIR="/lib/lustre" - -. $SRCDIR/common.sh - -setup_opts "$@" - -setup_portals -setup_lustre -setup_ldlm - -setup_server old_fs -setup_client diff --git a/lustre/tests/llsetup.sh b/lustre/tests/llsetup.sh deleted file mode 100644 index 4828f26..0000000 --- a/lustre/tests/llsetup.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -vx - -SRCDIR="`dirname $0`/" -[ -f $SRCDIR/common.sh ] || SRCDIR="/lib/lustre" - -. $SRCDIR/common.sh - -setup_opts "$@" - -setup_portals || exit $? -setup_lustre || exit $? -setup_ldlm || exit $? - -setup_server new_fs || exit $? -setup_client || exit $? diff --git a/lustre/tests/llsimple.sh b/lustre/tests/llsimple.sh deleted file mode 100755 index d22ddc6..0000000 --- a/lustre/tests/llsimple.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -SRCDIR="`dirname $0`/" -[ -f $SRCDIR/common.sh ] || SRCDIR="/lib/lustre" - -. $SRCDIR/common.sh - -setup_opts "$@" - -setup_portals || exit $? -setup_lustre || exit $? diff --git a/lustre/tests/local.sh b/lustre/tests/local.sh deleted file mode 100755 index 2132801..0000000 --- a/lustre/tests/local.sh +++ /dev/null @@ -1,39 +0,0 @@ - -#!/bin/bash - -config=${1:-local.xml} - -LMC="${LMC:-../utils/lmc} -m $config" -TMP=${TMP:-/tmp} - -MDSDEV=${MDSDEV:-$TMP/mds1} -MDSSIZE=${MDSSIZE:-50000} - -OSTDEV=${OSTDEV:-$TMP/ost1} -OSTSIZE=${OSTSIZE:-200000} - -kver=`uname -r | cut -d "." -f 1,2` - -case $kver in - 2.4) FSTYPE="--fstype=extN" ;; - 2.5) FSTYPE="--fstype=ext3" ;; - *) echo "Kernel version $kver not supported" - exit 1 - ;; -esac - - -rm -f $config - -# create nodes -${LMC} --add node --node localhost || exit 10 -${LMC} --add net --node localhost --nid localhost --nettype tcp || exit 11 - -# configure mds server -${LMC} --add mds --node localhost --mds mds1 $FSTYPE --dev $MDSDEV --size $MDSSIZE || exit 20 - -# configure ost -${LMC} --add ost --node localhost --ost obd1 $FSTYPE --dev $OSTDEV --size $OSTSIZE || exit 30 - -# create client config -${LMC} --add mtpt --node localhost --path /mnt/lustre --mds mds1 --ost obd1 || exit 40 diff --git a/lustre/tests/lov.sh b/lustre/tests/lov.sh deleted file mode 100755 index c0b2839..0000000 --- a/lustre/tests/lov.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -config=${1:-lov.xml} - -LMC=${LMC:-../utils/lmc} -TMP=${TMP:-/tmp} - -MDSDEV=${MDSDEV:-$TMP/mds1} -MDSSIZE=${MDSSIZE:-50000} - -OSTDEV1=${OSTDEV1:-$TMP/ost1} -OSTDEV2=${OSTDEV2:-$TMP/ost2} -OSTDEV3=${OSTDEV3:-$TMP/ost3} -OSTSIZE=${OSTSIZE:-100000} - -STRIPE_BYTES=65536 -STRIPES_PER_OBJ=2 # 0 means stripe over all OSTs - -# create nodes -${LMC} -o $config --add net --node localhost --nid localhost --nettype tcp || exit 1 - -# configure mds server -${LMC} -m $config --format --add mds --node localhost --mds mds1 --dev $MDSDEV --size $MDSSIZE || exit 10 - -# configure ost -${LMC} -m $config --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 || exit 20 -${LMC} -m $config --add ost --node localhost --lov lov1 --dev $OSTDEV1 --size $OSTSIZE || exit 21 -${LMC} -m $config --add ost --node localhost --lov lov1 --dev $OSTDEV2 --size $OSTSIZE || exit 22 -${LMC} -m $config --add ost --node localhost --lov lov1 --dev $OSTDEV3 --size $OSTSIZE || exit 23 - -# create client config -${LMC} -m $config --add mtpt --node localhost --path /mnt/lustre --mds mds1 --lov lov1 || exit 30 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 0401bf5..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 - -h2tcp () { - echo "${1}" -} -BATCH=/tmp/lmc-batch.$$ -save_cmd() { - echo "$@" >> $BATCH -} - -[ -f $config ] && rm $config - -# Client node -${LMC} --add net --node client --tcpbuf $TCPBUF --nid '*' --nettype 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} --add net --node $OST --tcpbuf $TCPBUF --nid $OST --nettype tcp || exit 1 - # the device on the server - ${LMC} --add ost --node $OST --obd obd_$OST --obdtype=obdecho || exit 3 - # osc on client - ${LMC} --add oscref --node client --osc OSC_obd_$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 29ec215..0000000 --- a/lustre/tests/mcr-mds-failover-config.sh +++ /dev/null @@ -1,50 +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=${OST:-ba50} -UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt} -OST_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST` -[ "$OST_UUID" ] && OST_UUID="--ostuuid=$OST_UUID" || echo "$OST: no UUID" -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' -} - -h2tcp () { - echo "${1}" -} - - -# create client node -$LMC -o $CONFIG --add net --node client --nid '*' --nettype elan -$LMC -m $CONFIG --add net --router --node mcr21 --tcpbuf $TCPBUF --nid `h2tcp $GW_NODE` --nettype tcp -$LMC -m $CONFIG --add net --router --node mcr21 --nid `h2elan $GW_NODE` --nettype elan -$LMC -m $CONFIG --add route --node $GW_NODE --nettype elan --gw `h2elan $GW_NODE` --lo $CLIENT_ELAN - -# create MDS node entries -for mds in $MDSNODES; do - elanaddr=`$LUSTRE_QUERY -h emcri -s id=$mds -e` - $LMC -m $CONFIG --add net --node $mds --nid $elanaddr --nettype elan - $LMC -m $CONFIG --add mds --node $mds --mds mds_$mds --dev $MDS_DEVICE --size $MDS_SIZE -done - -# create OST node entry -$LMC -m $CONFIG --add net --node $OST --tcpbuf $TCPBUF --nid $OST --nettype tcp -$LMC -m $CONFIG --add ost --node $OST --ost ost_$OST $OST_UUID --dev bluearc -$LMC -m $CONFIG --add route --node $GW_NODE --nettype tcp --gw `h2tcp $GW_NODE` --lo $OST - -# mount -$LMC -m $CONFIG --add mtpt --node client --path /mnt/lustre --mds mds_$ACTIVEMDS --lov ost_$OST diff --git a/lustre/tests/mcr-routed-config.sh b/lustre/tests/mcr-routed-config.sh deleted file mode 100755 index 3b1d961..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=32 -GW_START=0 -GW_CNT=16 -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=38 -CLIENT_HI=191 - -TCPBUF=1048576 - -h2elan () { - echo $1 | sed 's/[^0-9]*//g' -} - -h2tcp () { - 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} --add net --node $MDS --nid `h2elan $MDS` --nettype elan || exit 1 -${LMC} --add mds --node $MDS --mds mds1 --dev /tmp/mds1 --size 100000 || exit 1 -${LMC} --add lov --lov lov1 --mds mds1 --stripe_sz 65536 --stripe_cnt 1 --stripe_pattern 0 - -# Client node -#${LMC} --add net --node client --tcpbuf $TCPBUF --nid '*' --nettype tcp || exit 1 -${LMC} --add net --node client --nid '*' --nettype elan || exit 1 -${LMC} --add mtpt --node client --path /mnt/lustre --mds mds1 --lov 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} --add net --router --node $gwnode --tcpbuf $TCPBUF --nid `h2tcp $gwnode` --nettype tcp || exit 1 - ${LMC} --add net --node $gwnode --nid `h2elan $gwnode` --nettype elan || exit 1 - ${LMC} --add route --node $gwnode --nettype elan --gw `h2elan $gwnode` --lo `h2elan $CLIENT_LO` --hi `h2elan $CLIENT_HI` || exit 2 - - let i=0 - while (( $i < $server_per_gw )); - do - OST=${OSTBASE}$server - echo "server: $OST" - OST_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST` - [ "$OST_UUID" ] && OST_UUID="--ostuuid $OST_UUID" || echo "$OST: no UUID" - # server node - ${LMC} --add net --node $OST --tcpbuf $TCPBUF --nid $OST --nettype tcp || exit 1 - # the device on the server - ${LMC} --add ost --lov lov1 --node $OST $OBD_UUID --dev bluearc || exit 3 - # route to server - ${LMC} --add route --node $gwnode --nettype tcp --gw `h2tcp $gwnode` --lo $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 4777337..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' -} - -h2tcp () { - echo "${1}" -} - -[ -f $config ] && rm $config - -# Client node -${LMC} --add net --node client --nid '*' --nettype elan || exit 1 -# Router node -${LMC} --add net --router --node $ROUTER --tcpbuf $TCPBUF --nid `h2tcp $ROUTER` --nettype tcp || exit 1 -${LMC} --add net --node $ROUTER --nid `h2elan $ROUTER` --nettype elan|| exit 1 -${LMC} -m $config --add route --node $ROUTER --nettype elan --gw `h2elan $ROUTER` --lo `h2elan $CLIENT_LO` --hi `h2elan $CLIENT_HI` || exit 2 - -for s in $SERVERS - do - # server node - ${LMC} --add net --node $s --tcpbuf $TCPBUF --nid $s --nettype tcp || exit 1 - # route to server - ${LMC} --add route --node $ROUTER --nettype tcp --gw `h2tcp $ROUTER` --lo $s || exit 2 - # the device on the server - ${LMC} --add ost --node $s --obd obd_$s --obdtype=obdecho || exit 3 - # attach to the device on the client (this would normally be a mount) - ${LMC} --add oscref --node client --osc OSC_obd_$s || exit 4 -done diff --git a/lustre/tests/mcreate.c b/lustre/tests/mcreate.c deleted file mode 100644 index 9d48b11..0000000 --- a/lustre/tests/mcreate.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 = mknod(argv[1], S_IFREG | 0644, 0); - if (rc) { - printf("mknod(%s) error: %s\n", argv[1], strerror(errno)); - } - return rc; -} diff --git a/lustre/tests/mcrlov.sh b/lustre/tests/mcrlov.sh deleted file mode 100755 index cce8878..0000000 --- a/lustre/tests/mcrlov.sh +++ /dev/null @@ -1,52 +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' -} - -h2tcp () { - echo "${1}" -} - -[ -f $config ] && rm $config - -# Client node -${LMC} --add net --node client --nid '*' --nettype elan || exit 1 -# Router node -${LMC} --add net --router --node $ROUTER --tcpbuf $TCPBUF --nid `h2tcp $ROUTER` --nettype tcp || exit 1 -${LMC} --add net --node $ROUTER --nid `h2elan $ROUTER` --nettype elan|| exit 1 -${LMC} --add route --node $ROUTER --gw `h2elan $ROUTER` --lo `h2elan $CLIENT_LO` --hi `h2elan $CLIENT_HI` --nettype elan || exit 2 - -${LMC} --add net --node $MDS --nid `h2elan $MDS` --nettype elan || exit 1 -${LMC} --add mds --node $MDS --mds mds1 --dev $TMP/mds1 --size 100000 || exit 1 -${LMC} --add lov --lov lov1 --mds mds1 --stripe_sz 65536 --stripe_cnt 0 --stripe_pattern 0 || exit 1 - -${LMC} --add mtpt --node client --path /mnt/lustre --mds mds1 --lov lov1 - -for s in $SERVERS - do - # server node - ${LMC} --add net --node $s --tcpbuf $TCPBUF --nid $s --nettype tcp || exit 1 - # route to server - ${LMC} --add route --node $ROUTER --nettype tcp --gw `h2tcp $ROUTER` --lo $s || exit 2 - # the device on the server - #${LMC} --format --lov lov1 --node $s --ost bluearc || exit 3 - ${LMC} --add ost --lov lov1 --node $s --dev bluearc --format || 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, 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 07de3ed..0000000 --- a/lustre/tests/mount2.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -config=${1:-mount2.xml} - -SRCDIR=`dirname $0` -PATH=$SRCDIR:$SRCDIR/../utils:$PATH -LMC="${LMC:-lmc} -m $config" -TMP=${TMP:-/tmp} - -MDSDEV=${MDSDEV:-$TMP/mds1} -MDSSIZE=${MDSSIZE:-50000} - -OSTDEV=${OSTDEV:-$TMP/ost1} -OSTSIZE=${OSTSIZE:-200000} - -rm -f $config - -# create nodes -${LMC} --add node --node localhost || exit 10 -${LMC} --add net --node localhost --nid localhost --nettype tcp || exit 11 - -# configure mds server -${LMC} --add mds --node localhost --mds mds1 --dev $MDSDEV --size $MDSSIZE || exit 20 - -# configure ost -${LMC} --add ost --node localhost --ost ost1 --dev $OSTDEV --size $OSTSIZE || exit 30 - -# create client config -${LMC} --add mtpt --node localhost --path /mnt/lustre1 --mds mds1 --ost ost1 || exit 40 -${LMC} --add mtpt --node localhost --path /mnt/lustre2 --mds mds1 --ost ost1 || exit 40 diff --git a/lustre/tests/mount2fs.sh b/lustre/tests/mount2fs.sh deleted file mode 100644 index 27b570d..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 --add net --node $MDSNODE --nid $MDSNODE --nettype tcp || exit 1 -${LMC} -m $config --add net --node $OSTNODE --nid $OSTNODE --nettype tcp || exit 2 -${LMC} -m $config --add net --node $CLIENT --nid $CLIENT --nettype tcp || exit 3 - -# configure mds server -${LMC} -m $config --format --add mds --node $MDSNODE --mds mds1 --dev $MDSDEV --size $MDSSIZE ||exit 10 -${LMC} -m $config --format --add mds --node $MDSNODE --mds mds2 --dev $MDSDEV2 --size $MDSSIZE ||exit 10 - -# configure ost -${LMC} -m $config --add lov --lov lov1 --mds mds1 --stripe_sz 65536 --stripe_cnt 0 --stripe_pattern 0 || exit 20 -${LMC} -m $config --add lov --lov lov2 --mds mds2 --stripe_sz 65536 --stripe_cnt 0 --stripe_pattern 0 || exit 20 -${LMC} -m $config --add ost --node $OSTNODE --lov lov1 --dev $OSTDEV1 --size $OSTSIZE || exit 21 -${LMC} -m $config --add ost --node $OSTNODE --lov lov2 --dev $OSTDEV2 --size $OSTSIZE || exit 22 - -# create client config -${LMC} -m $config --add mtpt --node $CLIENT --path /mnt/lustre --mds mds1 --lov lov1 || exit 30 -${LMC} -m $config --add mtpt --node $CLIENT --path /mnt/lustre2 --mds mds2 --lov lov2 || exit 30 - - - - diff --git a/lustre/tests/multifstat.c b/lustre/tests/multifstat.c deleted file mode 100644 index fa510bc..0000000 --- a/lustre/tests/multifstat.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - int fd1, fd2; - struct stat st1, st2; - - if (argc != 3) { - printf("Usage %s file1 file2\n", argv[0]); - return 1; - } - - - fd1 = open(argv[1], O_CREAT| O_RDWR, 0666); - if (fd1 == -1) { - printf("Error opening %s: %s\n", argv[1], strerror(errno)); - return errno; - } - - fd2 = open(argv[2], O_RDONLY); - if (fd2 == -1) { - printf("Error opening %s: %s\n", argv[2], strerror(errno)); - return errno; - } - - sleep(1); - - if ( write(fd1, "hello", strlen("hello")) != strlen("hello")) { - printf("Error writing: %s\n", strerror(errno)); - return errno; - } - - if ( fstat(fd1, &st1) ) { - printf("Error statting %s: %s\n", argv[1], strerror(errno)); - return errno; - } - - if ( fstat(fd2, &st2) ) { - printf("Error statting %s: %s\n", argv[2], strerror(errno)); - return errno; - } - - if ( st1.st_size != st2.st_size ) { - printf("Sizes don't match %ld, %ld\n", - st1.st_size, st2.st_size); - return 1; - } - - if ( st1.st_mtime != st2.st_mtime ) { - printf("Mtimes don't match %ld, %ld\n", - st1.st_mtime, st2.st_mtime); - return 1; - } - - return 0; -} diff --git a/lustre/tests/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/open_delay.c b/lustre/tests/open_delay.c deleted file mode 100644 index de4815c..0000000 --- a/lustre/tests/open_delay.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - int fd; - - if (argc != 2) { - printf("Usage %s \n", argv[0]); - exit(1); - } - - fd = open(argv[1], O_RDONLY | O_LOV_DELAY_CREATE); - if (fd == -1) { - printf("Error opening %s\n", argv[1]); - exit(1); - } - - return 0; -} diff --git a/lustre/tests/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 e7671c8..0000000 --- a/lustre/tests/openunlink.c +++ /dev/null @@ -1,147 +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) -{ - char *fname, *fname2; - int fd, rc; - - if (argc < 2 || argc > 3) { - fprintf(stderr, "usage: %s filename [filename2]\n", argv[0]); - exit(1); - } - - fname = argv[1]; - if (argc == 3) - fname2 = argv[2]; - else - fname2 = argv[1]; - - fprintf(stderr, "opening\n"); - fd = open(fname, 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); - } - - if (argc == 3) { - fprintf(stderr, "closing %s\n", fname); - rc = close(fd); - if (rc) { - fprintf(stderr, "close (normal) %s\n", strerror(errno)); - exit(1); - } - - fprintf(stderr, "opening %s\n", fname2); - fd = open(fname2, O_RDWR); - if (fd == -1) { - fprintf(stderr, "open (unlink) %s\n", strerror(errno)); - exit(1); - } - - fprintf (stderr, "unlinking %s\n", fname2); - rc = unlink(fname2); - if (rc) { - fprintf(stderr, "unlink %s\n", strerror(errno)); - exit(1); - } - - if (access(fname2, F_OK) == 0) { - fprintf(stderr, "%s still exists\n", fname2); - exit(1); - } - } else { - printf("unlink %s and press enter\n", fname); - getc(stdin); - } - - if (access(fname, F_OK) == 0) { - fprintf(stderr, "%s still exists\n", fname); - exit(1); - } - - 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/lustre/fail_loc" - do_client "$1 & sleep ${TIMEOUT:-5}; sleep 2; kill \$!" - do_mds "echo 0 > /proc/sys/lustre/fail_loc" -} - -make_config() { - rm -f $CONFIG - for NODE in $CLIENT $MDSNODE $OSTNODE; do - lmc -m $CONFIG --add net --node $NODE --nid `h2$NETWORKTYPE $NODE` \ - --nettype $NETWORKTYPE || exit 4 - done - lmc -m $CONFIG --add mds --node $MDSNODE --mds mds1 --dev $MDSDEV \ - --size $MDSSIZE || exit 5 - lmc -m $CONFIG --add ost --node $OSTNODE --ost ost1 --dev $OSTDEV \ - --size $OSTSIZE || exit 6 - lmc -m $CONFIG --add mtpt --node $CLIENT --path $MOUNTPT --mds mds1 \ - --ost ost1 || exit 7 -} - -start_mds() { - do_mds "lconf $@ $CONFIG" -} - -shutdown_mds() { - do_mds "lconf $@ --cleanup $CONFIG" -} - -start_ost() { - do_ost "lconf $@ $CONFIG" -} - -shutdown_ost() { - do_ost "lconf $@ --cleanup $CONFIG" -} - -mount_client() { - do_client "lconf $@ $CONFIG" -} - -unmount_client() { - do_client "lconf $@ --cleanup $CONFIG" -} - -setup() { - make_config - start_mds ${REFORMAT:---reformat} - start_ost ${REFORMAT:---reformat} - mount_client --timeout=${TIMEOUT:-5} --recovery_upcall=/bin/true -} - -cleanup() { - do_mds "echo 0 > /proc/sys/lustre/fail_loc" - unmount_client $@ || true - shutdown_mds $@ || true - shutdown_ost $@ || true -} - -wait_for_timeout() { - # wait to make sure we enter recovery - # it'd be better if the upcall notified us somehow, I think - sleep $(( ${TIMEOUT:-5} + 2 )) -} - -try_to_cleanup() { - kill -INT $! - unmount_client --force - mount_client --timeout=${TIMEOUT:-5} --recovery_upcall=/bin/true -} - -if [ ! -z "$ONLY" ]; then - eval "$ONLY" - exit $? -fi - -setup -drop_request "mcreate /mnt/lustre/1" & wait_for_timeout -try_to_cleanup - -drop_request "tchmod 111 /mnt/lustre/2" & wait_for_timeout -try_to_cleanup - -drop_request "statone /mnt/lustre/2" & wait_for_timeout -try_to_cleanup - -do_client "cp /etc/resolv.conf /mnt/lustre/resolv.conf" -drop_request "cat /mnt/lustre/resolv.conf > /dev/null" & wait_for_timeout -try_to_cleanup - -drop_request "mv /mnt/lustre/resolv.conf /mnt/lustre/renamed" & wait_for_timeout -try_to_cleanup - -drop_request "mlink /mnt/lustre/renamed-again /mnt/lustre/link1" & wait_for_timeout -try_to_cleanup - -drop_request "munlink /mnt/lustre/link1" & wait_for_timeout -try_to_cleanup - -cleanup diff --git a/lustre/tests/recovery-small.sh b/lustre/tests/recovery-small.sh deleted file mode 100755 index 7425e57..0000000 --- a/lustre/tests/recovery-small.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/sh - -set -ex - -LUSTRE=${LUSTRE:-`dirname $0`/..} -PATH=$PATH:$LUSTRE/utils:$LUSTRE/tests - -. $LUSTRE/../ltest/functional/llite/common/common.sh - -PDSH='pdsh -S -w' - -# XXX I wish all this stuff was in some default-config.sh somewhere -MDSNODE=${MDSNODE:-mdev6} -OSTNODE=${OSTNODE:-mdev7} -CLIENT=${CLIENTNODE:-mdev8} -NETWORKTYPE=${NETWORKTYPE:-tcp} -MOUNTPT=${MOUNTPT:-/mnt/lustre} -CONFIG=recovery-small.xml -MDSDEV=/tmp/mds -OSTDEV=/tmp/ost -MDSSIZE=100000 -OSTSIZE=100000 - -do_mds() { - $PDSH $MDSNODE "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@" -} - -do_client() { - $PDSH $CLIENT "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@" -} - -do_ost() { - $PDSH $OSTNODE "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@" -} - -drop_request() { - do_mds "echo 0x121 > /proc/sys/lustre/fail_loc" - do_client "$1" - do_mds "echo 0 > /proc/sys/lustre/fail_loc" -} - -drop_reply() { - do_mds "echo 0x120 > /proc/sys/lustre/fail_loc" - do_client "$@" - do_mds "echo 0 > /proc/sys/lustre/fail_loc" -} - -make_config() { - rm -f $CONFIG - for NODE in $CLIENT $MDSNODE $OSTNODE; do - lmc -m $CONFIG --add net --node $NODE --nid `h2$NETWORKTYPE $NODE` \ - --nettype $NETWORKTYPE || exit 4 - done - lmc -m $CONFIG --add mds --node $MDSNODE --mds mds1 --dev $MDSDEV \ - --size $MDSSIZE || exit 5 - lmc -m $CONFIG --add ost --node $OSTNODE --ost ost1 --dev $OSTDEV \ - --size $OSTSIZE || exit 6 - lmc -m $CONFIG --add mtpt --node $CLIENT --path $MOUNTPT --mds mds1 \ - --ost ost1 || exit 7 -} - -start_mds() { - do_mds "lconf $@ $CONFIG" -} - -shutdown_mds() { - do_mds "lconf $@ --cleanup $CONFIG" -} - -start_ost() { - do_ost "lconf $@ $CONFIG" -} - -shutdown_ost() { - do_ost "lconf $@ --cleanup $CONFIG" -} - -mount_client() { - do_client "lconf $@ $CONFIG" -} - -unmount_client() { - do_client "lconf $@ --cleanup $CONFIG" -} - -setup() { - make_config - start_mds ${REFORMAT:---reformat} - start_ost ${REFORMAT:---reformat} - # XXX we should write our own upcall, when we move this somewhere better. - mount_client --timeout=${TIMEOUT:-5} \ - --recovery_upcall=$PWD/../../ltest/functional/llite/09/client-upcall.sh -} - -cleanup() { - do_mds "echo 0 > /proc/sys/lustre/fail_loc" - unmount_client $@ || true - shutdown_mds $@ || true - shutdown_ost $@ || true -} - -replay() { - do_mds "sync" - do_mds 'echo -e "device \$mds1\\nprobe\\nnotransno\\nreadonly" | lctl' - do_client "$1" & - shutdown_mds -f - start_mds - wait - do_client "df -h $MOUNTPT" # trigger failover, if we haven't already -} - -if [ ! -z "$ONLY" ]; then - eval "$ONLY" - exit $? -fi - -setup -drop_request "mcreate /mnt/lustre/1" -drop_reply "mcreate /mnt/lustre/2" -# replay "mcreate /mnt/lustre/3" - -drop_request "tchmod 111 /mnt/lustre/2" -drop_reply "tchmod 666 /mnt/lustre/2" -# replay "tchmod 444 /mnt/lustre/2" - -drop_request "statone /mnt/lustre/2" -drop_reply "statone /mnt/lustre/2" -# replay "statone /mnt/lustre/2" - -do_client "cp /etc/resolv.conf /mnt/lustre/resolv.conf" -drop_request "cat /mnt/lustre/resolv.conf > /dev/null" -drop_reply "cat /mnt/lustre/resolv.conf > /dev/null" - -drop_request "mv /mnt/lustre/resolv.conf /mnt/lustre/renamed" -drop_reply "mv /mnt/lustre/renamed /mnt/lustre/renamed-again" - -drop_request "mlink /mnt/lustre/renamed-again /mnt/lustre/link1" -drop_reply "mlink /mnt/lustre/renamed-again /mnt/lustre/link2" - -drop_request "munlink /mnt/lustre/link1" -drop_reply "munlink /mnt/lustre/link2" - - -cleanup diff --git a/lustre/tests/rename.pl b/lustre/tests/rename.pl deleted file mode 100644 index 3ba9368..0000000 --- a/lustre/tests/rename.pl +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/perl -use strict; -use diagnostics; -use Getopt::Long; - -sub usage () { - print "Usage: $0 \n"; - print "example: $0 --count=2 /mnt/lustre 50\n"; - print " will test in /mnt/lustre1 and /mnt/lustre2\n"; - print " $0 --count=0 /mnt/lustre 50\n"; - print " will test in /mnt/lustre only\n"; - exit; -} -my ($j, $k, $d, $f1, $f2, $path, $silent); -my $count = 0; -my $create = 10; - -GetOptions("silent!"=> \$silent, - "count=i" => \$count, - "create=i" => \$create); - -my $mtpt = shift || usage(); -my $i = shift || usage(); -my $total = $i; -my $files = 6; -my $dirs = 3; -my $mcreate = 0; # should we use mcreate or open? - -my $which = ""; -if ($count > 0) { - $which = int(rand() * $count) + 1; -} - -$k = $dirs; -if ($create == 0) { - $k = 0; -} -while ($k--) { - $path = "$mtpt$which/$k"; - my $rc = mkdir $path, 0755; - print "mkdir $path failed: $!\n" if !$rc; - $j = $files; - while ($j--) { - `./mcreate $path/$j`; - } -} - -while ($i--) { - my $which = ""; - if ($count > 0) { - $which = int(rand() * $count) + 1; - } - $d = int(rand() * $dirs); - $f1 = int(rand() * $files); - $f2 = int(rand() * $files); - print "[$$] $mtpt$which/$d/$f1 $mtpt$which/$d/$f2 ...\n" if !$silent; - my $rc = rename "$mtpt$which/$d/$f1", "$mtpt$which/$d/$f2"; - print "[$$] done: $rc\n" if !$silent; - if (($total - $i) % 100 == 0) { - print STDERR "[" . $$ . "]" . ($total - $i) . " operations\n"; - } -} - -$k = $dirs; -if ($create == 0) { - $k = 0; -} -while ($k--) { - $path = "$mtpt$which/$k"; - $j = $files; - while ($j--) { - unlink "$path/$j"; - } - my $rc = rmdir $path; - print "rmdir $path failed: $!\n" if !$rc; -} - -print "Done.\n"; diff --git a/lustre/tests/rundbench b/lustre/tests/rundbench deleted file mode 100755 index cbf6a65..0000000 --- a/lustre/tests/rundbench +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -#[ -e /proc/sys/portals/debug ] && echo 0 > /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 c2eec04..0000000 --- a/lustre/tests/runiozone +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -[ -z "$SIZE" ] && SIZE=5g -[ -z "$COUNT" ] && COUNT=100 -[ -z "$VERIFY" ] && VERIFY="-+d" -[ -z "$ODIR" ] && ODIR="-I" -[ -z "$REC" ] && REC=64 -[ -z "$FILE" ] && FILE=/mnt/lustre/iozone.$$ -[ $1 ] && SIZE=$1 -LOOP=0 -rm -f endiozone -echo 0 > /proc/sys/portals/debug -while date; do - LOOP=`expr $LOOP + 1` - echo "Test #$LOOP" - iozone $VERIFY $ODIR -r $REC -i 0 -i 1 -f $FILE -s $SIZE 2>&1 || exit $? - [ -f endiozone -o $LOOP -ge $COUNT ] && 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 4d86248..0000000 --- a/lustre/tests/runregression-brw.sh +++ /dev/null @@ -1,111 +0,0 @@ -#!/bin/sh -SRCDIR="`dirname $0`/" -export PATH=/sbin:/usr/sbin:$SRCDIR:$PATH - -LOOPS=${LOOPS:-1} -COUNT=${COUNT:-1000000} -COUNT_10=`expr $COUNT / 10` -COUNT_100=`expr $COUNT / 100` - -ENDRUN=endrun-`hostname` - -ECHONAME="`lctl 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 () { - lctl --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 - - lctl --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=`lctl --device \\$$ECHONAME create 1 | awk '/is object id/ { print $6 }'` && echo "created object $OID" -[ -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 i in `seq $LOOPS`; do - PG=1 - PGVW=${PGVW:-16} - PGVR=${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 6de9a6c..0000000 --- a/lustre/tests/runregression-net.sh +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/sh -SRCDIR="`dirname $0`/" -export PATH=/sbin:/usr/sbin:$SRCDIR/../utils:$PATH - -COUNT=${COUNT:-1000000} -COUNT_10=`expr $COUNT / 10` -COUNT_100=`expr $COUNT / 100` -COUNT_1000=`expr $COUNT / 1000` - -ENDRUN=endrun-`hostname` - -ECHONAME="`lctl 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 () { - lctl --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 - - lctl --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=`lctl --device \\$$ECHONAME create 1 | awk '/is object id/ { print $6 }'` && echo "created object $OID" -[ -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=${PGV:-16} - ;; - test_brw_read) - PG=1 - PGV=${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 - - echo 0 > /proc/sys/portals/debug - 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 - -lctl --device \$$ECHONAME destroy $OID diff --git a/lustre/tests/runslabinfo b/lustre/tests/runslabinfo deleted file mode 100755 index eba407d..0000000 --- a/lustre/tests/runslabinfo +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -while sleep 1 ; do - echo '-----------------------' - egrep "ll_|ldlm|filp|dentry|inode|portals|size-[0-9]* " /proc/slabinfo -done diff --git a/lustre/tests/runtests b/lustre/tests/runtests deleted file mode 100755 index e59f5f4..0000000 --- a/lustre/tests/runtests +++ /dev/null @@ -1,130 +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 -} - -log() { - echo "$*" - lctl mark "$*" -} - -export PATH=/sbin:/usr/sbin:$SRCDIR:$SRCDIR/../utils:$PATH - -ERROR= -SRC=/etc -[ "$COUNT" ] || COUNT=1000 - -[ "$LCONF" ] || LCONF=$SRCDIR/../utils/lconf - -[ "$MCREATE" ] || MCREATE=$SRCDIR/../tests/mcreate - -[ "$MKDIRMANY" ] || MKDIRMANY=$SRCDIR/../tests/mkdirmany - -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... -log "touching $OSCMT" -touch $OSCMT || fail "can't touch $OSCMT" 2 -HOSTS=$OSCMT/hosts.$$ - -# this will cause the following cp to trigger bug #620096 -log "create an empty file $HOSTS" -mcreate $HOSTS - -log "copying /etc/hosts to $HOSTS" -cp /etc/hosts $HOSTS || fail "can't cp /etc/hosts to $HOSTS" 3 -log "comparing /etc/hosts and $HOSTS" -diff -u /etc/hosts $HOSTS || fail "$HOSTS different" 4 -log "renaming $HOSTS to $HOSTS.ren" -mv $HOSTS $HOSTS.ren || fail "can't rename $HOSTS to $HOSTS.ren" 5 -log "copying /etc/hosts to $HOSTS again" -cp /etc/hosts $HOSTS || fail "can't cp /etc/hosts to $HOSTS again" 6 -log "truncating $HOSTS" -> $HOSTS || fail "can't truncate $HOSTS" 8 -log "removing $HOSTS" -rm $HOSTS || fail "can't remove $HOSTS" 9 - -DST=$OSCMT/runtest.$$ -# let's start slowly here... -log "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` -log "copying files from $SRC to $DST$SRC" -tar cf - $FILES | tar xvf - -C $DST || fail "copying $SRC" 11 - -log "comparing newly copied files" -for f in $FILES; do - [ $V ] && log "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 - -log "comparing previously copied files" -for f in $FILES; do - [ $V ] && log "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 - -log "renaming $HOSTS.ren to $HOSTS" -mv $HOSTS.ren $HOSTS || fail "can't rename $HOSTS.ren to $HOSTS" 32 -log "truncating $HOSTS" -> $HOSTS || fail "can't truncate $HOSTS" 34 -log "removing $HOSTS" -rm $HOSTS || fail "can't remove $HOSTS again" 36 -log "removing $DST" -rm -r $V $DST || fail "can't remove $DST" 37 - -# mkdirmany test (bug 589) -log "running mkdirmany $OSCMT/base$$ 100" -$MKDIRMANY $OSCMT/base$$ 100 || fail "mkdirmany failed" -log "removing mkdirmany directories" -rmdir $OSCMT/base$$* || fail "mkdirmany cleanup failed" - -log "done" - -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 c3e201f..0000000 --- a/lustre/tests/sanity.sh +++ /dev/null @@ -1,558 +0,0 @@ -#!/bin/bash - -set -e - -SRCDIR=`dirname $0` -PATH=$SRCDIR:$SRCDIR/../utils:$PATH - -CHECKSTAT=${CHECKSTAT:-"./checkstat -v"} -CREATETEST=${CREATETEST:-createtest} -LFIND=${LFIND:-lfind} -LSTRIPE=${LSTRIPE:-lstripe} -MCREATE=${MCREATE:-mcreate} -TOEXCL=${TOEXCL:-toexcl} - -MOUNT=${MOUNT:-/mnt/lustre} -DIR=${DIR:-$MOUNT} -export NAME=$NAME -clean() { - echo -n "cln.." - sh llmountcleanup.sh > /dev/null || exit 20 -} -CLEAN=${CLEAN:-clean} -start() { - echo -n "mnt.." - sh llrmount.sh > /dev/null || exit 10 - echo "done" -} -START=${START:-start} - -log() { - echo "$*" - lctl mark "$*" -} - -error() { - echo FAIL - exit 1 -} - -pass() { - echo PASS -} - -mount | grep $MOUNT || sh llmount.sh - -log '== touch .../f ; rm .../f ======================== test 0' -touch $DIR/f -$CHECKSTAT -t file $DIR/f || error -rm $DIR/f -$CHECKSTAT -a $DIR/f || error -pass -$CLEAN -$START - -log '== mkdir .../d1; mkdir .../d1/d2 ================= test 1' -mkdir $DIR/d1 -mkdir $DIR/d1/d2 -$CHECKSTAT -t dir $DIR/d1/d2 || error -pass -$CLEAN -$START - -log '== rmdir .../d1/d2; rmdir .../d1 ================= test 1b' -rmdir $DIR/d1/d2 -rmdir $DIR/d1 -$CHECKSTAT -a $DIR/d1 || error -pass -$CLEAN -$START - -log '== mkdir .../d2; touch .../d2/f ================== test 2' -mkdir $DIR/d2 -touch $DIR/d2/f -$CHECKSTAT -t file $DIR/d2/f || error -pass -$CLEAN -$START - -log '== rm -r .../d2; touch .../d2/f ================== test 2b' -rm -r $DIR/d2 -$CHECKSTAT -a $DIR/d2 || error -pass -$CLEAN -$START - -log '== mkdir .../d3 ================================== test 3' -mkdir $DIR/d3 -$CHECKSTAT -t dir $DIR/d3 || error -pass -$CLEAN -$START -log '== touch .../d3/f ================================ test 3b' -touch $DIR/d3/f -$CHECKSTAT -t file $DIR/d3/f || error -pass -$CLEAN -$START -log '== rm -r .../d3 ================================== test 3c' -rm -r $DIR/d3 -$CHECKSTAT -a $DIR/d3 || error -pass -$CLEAN -$START - -log '== mkdir .../d4 ================================== test 4' -mkdir $DIR/d4 -$CHECKSTAT -t dir $DIR/d4 || error -pass -$CLEAN -$START -log '== mkdir .../d4/d2 =============================== test 4b' -mkdir $DIR/d4/d2 -$CHECKSTAT -t dir $DIR/d4/d2 || error -pass -$CLEAN -$START - -log '== mkdir .../d5; mkdir .../d5/d2; chmod .../d5/d2 = test 5' -mkdir $DIR/d5 -mkdir $DIR/d5/d2 -chmod 0707 $DIR/d5/d2 -$CHECKSTAT -t dir -p 0707 $DIR/d5/d2 || error -pass -$CLEAN -$START - -log '== touch .../f6; chmod .../f6 ==================== test 6' -touch $DIR/f6 -chmod 0666 $DIR/f6 -$CHECKSTAT -t file -p 0666 $DIR/f6 || error -pass -$CLEAN -$START - -log '== mkdir .../d7; mcreate .../d7/f; chmod .../d7/f = test 7' -mkdir $DIR/d7 -$MCREATE $DIR/d7/f -chmod 0666 $DIR/d7/f -$CHECKSTAT -t file -p 0666 $DIR/d7/f || error -pass -$CLEAN -$START - -log '== mkdir .../d7; mcreate .../d7/f2; echo foo > .../d7/f2 = test 7b' -$MCREATE $DIR/d7/f2 -log -n foo > $DIR/d7/f2 -[ "`cat $DIR/d7/f2`" = "foo" ] || error -$CHECKSTAT -t file -s 3 $DIR/d7/f2 || error -pass -$CLEAN -$START - -log '== mkdir .../d8; touch .../d8/f; chmod .../d8/f == test 8' -mkdir $DIR/d8 -touch $DIR/d8/f -chmod 0666 $DIR/d8/f -$CHECKSTAT -t file -p 0666 $DIR/d8/f || error -pass -$CLEAN -$START - - -log '== mkdir .../d9 .../d9/d2 .../d9/d2/d3 =========== test 9' -mkdir $DIR/d9 -mkdir $DIR/d9/d2 -mkdir $DIR/d9/d2/d3 -$CHECKSTAT -t dir $DIR/d9/d2/d3 || error -pass -$CLEAN -$START - - -log '== mkdir .../d10 .../d10/d2; touch .../d10/d2/f = test 10' -mkdir $DIR/d10 -mkdir $DIR/d10/d2 -touch $DIR/d10/d2/f -$CHECKSTAT -t file $DIR/d10/d2/f || error -pass -$CLEAN -$START - -log '== mkdir .../d11 d11/d2; chmod .../d11/d2 ======= test 11' -mkdir $DIR/d11 -mkdir $DIR/d11/d2 -chmod 0666 $DIR/d11/d2 -chmod 0705 $DIR/d11/d2 -$CHECKSTAT -t dir -p 0705 $DIR/d11/d2 || error -pass -$CLEAN -$START - -log '== mkdir .../d12; touch .../d12/f; chmod .../d12/f == test 12' -mkdir $DIR/d12 -touch $DIR/d12/f -chmod 0666 $DIR/d12/f -chmod 0654 $DIR/d12/f -$CHECKSTAT -t file -p 0654 $DIR/d12/f || error -pass -$CLEAN -$START - -log '== mkdir .../d13; creat .../d13/f; .../d13/f; > .../d13/f == test 13' -mkdir $DIR/d13 -dd if=/dev/zero of=$DIR/d13/f count=10 -> $DIR/d13/f -$CHECKSTAT -t file -s 0 $DIR/d13/f || error -pass -$CLEAN -$START - -log '================================================== test 14' -mkdir $DIR/d14 -touch $DIR/d14/f -rm $DIR/d14/f -$CHECKSTAT -a $DIR/d14/f || error -pass -$CLEAN -$START - -log '================================================== test 15' -mkdir $DIR/d15 -touch $DIR/d15/f -mv $DIR/d15/f $DIR/d15/f2 -$CHECKSTAT -t file $DIR/d15/f2 || error -pass -$CLEAN -$START - -log '================================================== test 16' -mkdir $DIR/d16 -touch $DIR/d16/f -rm -rf $DIR/d16/f -$CHECKSTAT -a $DIR/d16/f || error -pass -$CLEAN -$START - -log '== symlinks: create, remove (dangling and real) == test 17' -mkdir $DIR/d17 -touch $DIR/d17/f -ln -s $DIR/d17/f $DIR/d17/l-exist -ln -s no-such-file $DIR/d17/l-dangle -ls -l $DIR/d17 -$CHECKSTAT -l $DIR/d17/f $DIR/d17/l-exist || error -$CHECKSTAT -f -t f $DIR/d17/l-exist || error -$CHECKSTAT -l no-such-file $DIR/d17/l-dangle || error -$CHECKSTAT -fa $DIR/d17/l-dangle || error -rm -f $DIR/l-dangle -rm -f $DIR/l-exist -$CHECKSTAT -a $DIR/l-dangle || error -$CHECKSTAT -a $DIR/l-exist || error -pass -$CLEAN -$START - -log "== touch .../f ; ls ... ========================= test 18" -touch $DIR/f -ls $DIR || error -pass -$CLEAN -$START - -log "== touch .../f ; ls -l ... ====================== test 19" -touch $DIR/f -ls -l $DIR -rm $DIR/f -$CHECKSTAT -a $DIR/f || error -pass -$CLEAN -$START - -log "== touch .../f ; ls -l ... ====================== test 20" -touch $DIR/f -rm $DIR/f -log "1 done" -touch $DIR/f -rm $DIR/f -log "2 done" -touch $DIR/f -rm $DIR/f -log "3 done" -$CHECKSTAT -a $DIR/f || error -pass -$CLEAN -$START - -log '== write to dangling link ======================== test 21' -mkdir $DIR/d21 -[ -f $DIR/d21/dangle ] && rm -f $DIR/d21/dangle -ln -s dangle $DIR/d21/link -echo foo >> $DIR/d21/link -cat $DIR/d21/dangle -$CHECKSTAT -t link $DIR/d21/link || error -$CHECKSTAT -f -t file $DIR/d21/link || error -pass -$CLEAN -$START - -log '== unpack tar archive as non-root user =========== test 22' -mkdir $DIR/d22 -which sudo && chown 4711 $DIR/d22 -SUDO=`which sudo 2> /dev/null` && SUDO="$SUDO -u #4711" || SUDO="" -echo '**** FIX THIS TEST ****' -SUDO="" -$SUDO tar cf - /etc/hosts /etc/sysconfig/network | $SUDO tar xfC - $DIR/d22 -ls -lR $DIR/d22/etc -$CHECKSTAT -t dir $DIR/d22/etc || error -[ -z "$SUDO" ] || $CHECKSTAT -u \#4711 $DIR/d22/etc || error -pass -$CLEAN -$START - -log '== O_CREAT|O_EXCL in subdir ====================== test 23' -mkdir $DIR/d23 -$TOEXCL $DIR/d23/f23 -$TOEXCL -e $DIR/d23/f23 || error -pass -$CLEAN -$START - -echo '== rename sanity ================================= test24' -echo '-- same directory rename' -log '-- test 24-R1: touch a ; rename a b' -mkdir $DIR/R1 -touch $DIR/R1/f -mv $DIR/R1/f $DIR/R1/g -$CHECKSTAT -t file $DIR/R1/g || error -pass -$CLEAN -$START - -log '-- test 24-R2: touch a b ; rename a b;' -mkdir $DIR/R2 -touch $DIR/R2/{f,g} -mv $DIR/R2/f $DIR/R2/g -$CHECKSTAT -a $DIR/R2/f || error -$CHECKSTAT -t file $DIR/R2/g || error -pass -$CLEAN -$START - -log '-- test 24-R3: mkdir a ; rename a b;' -mkdir $DIR/R3 -mkdir $DIR/R3/f -mv $DIR/R3/f $DIR/R3/g -$CHECKSTAT -a $DIR/R3/f || error -$CHECKSTAT -t dir $DIR/R3/g || error -pass -$CLEAN -$START - -log '-- test 24-R4: mkdir a b ; rename a b;' -mkdir $DIR/R4 -mkdir $DIR/R4/{f,g} -perl -e "rename \"$DIR/R4/f\", \"$DIR/R4/g\";" -$CHECKSTAT -a $DIR/R4/f || error -$CHECKSTAT -t dir $DIR/R4/g || error -pass -$CLEAN -$START - -echo '-- cross directory renames --' -log '-- test 24-R5: touch a ; rename a b' -mkdir $DIR/R5{a,b} -touch $DIR/R5a/f -mv $DIR/R5a/f $DIR/R5b/g -$CHECKSTAT -a $DIR/R5a/f || error -$CHECKSTAT -t file $DIR/R5b/g || error -pass -$CLEAN -$START - -log '-- test 24-R6: touch a ; rename a b' -mkdir $DIR/R6{a,b} -touch $DIR/R6a/f $DIR/R6b/g -mv $DIR/R6a/f $DIR/R6b/g -$CHECKSTAT -a $DIR/R6a/f || error -$CHECKSTAT -t file $DIR/R6b/g || error -pass -$CLEAN -$START - -log '-- test 24-R7: touch a ; rename a b' -mkdir $DIR/R7{a,b} -mkdir $DIR/R7a/f -mv $DIR/R7a/f $DIR/R7b/g -$CHECKSTAT -a $DIR/R7a/f || error -$CHECKSTAT -t dir $DIR/R7b/g || error -pass -$CLEAN -$START - -log '-- test 24-R8: touch a ; rename a b' -mkdir $DIR/R8{a,b} -mkdir $DIR/R8a/f $DIR/R8b/g -perl -e "rename \"$DIR/R8a/f\", \"$DIR/R8b/g\";" -$CHECKSTAT -a $DIR/R8a/f || error -$CHECKSTAT -t dir $DIR/R8b/g || error -pass -$CLEAN -$START - -echo "-- rename error cases" -log "-- test 24-R9 target error: touch f ; mkdir a ; rename f a" -mkdir $DIR/R9 -mkdir $DIR/R9/a -touch $DIR/R9/f -perl -e "rename \"$DIR/R9/f\", \"$DIR/R9/a\";" -$CHECKSTAT -t file $DIR/R9/f || error -$CHECKSTAT -t dir $DIR/R9/a || error -$CHECKSTAT -a file $DIR/R9/a/f || error -pass -$CLEAN -$START - -log "--test 24-R10 source does not exist" -mkdir $DIR/R10 -perl -e "rename \"$DIR/R10/f\", \"$DIR/R10/g\"" -$CHECKSTAT -t dir $DIR/R10 || error -$CHECKSTAT -a $DIR/R10/f || error -$CHECKSTAT -a $DIR/R10/g || error -pass -$CLEAN -$START - -echo '== symlink sanity ================================ test25' -log "--test 25.1 create file in symlinked directory" -mkdir $DIR/d25 -ln -s d25 $DIR/s25 -touch $DIR/s25/foo -pass -$CLEAN -$START - -log "--test 25.2 lookup file in symlinked directory" -$CHECKSTAT -t file $DIR/s25/foo -pass -$CLEAN -$START - -log "--test 26 multiple component symlink" -mkdir $DIR/d26 -mkdir $DIR/d26/d26-2 -ln -s d26/d26-2 $DIR/s26 -touch $DIR/s26/foo -pass -$CLEAN -$START - -log "--test 26.1 multiple component symlink at the end of a lookup" -ln -s d26/d26-2/foo $DIR/s26-2 -touch $DIR/s26-2 -pass -$CLEAN -$START - -log "--test 26.2 a chain of symlinks" -mkdir $DIR/d26.2 -touch $DIR/d26.2/foo -ln -s d26.2 $DIR/s26.2-1 -ln -s s26.2-1 $DIR/s26.2-2 -ln -s s26.2-2 $DIR/s26.2-3 -chmod 0666 $DIR/s26.2-3/foo -pass -$CLEAN -$START - -# recursive symlinks (bug 439) -log "--test 26.3 create multiple component recursive symlink" -ln -s d26-3/foo $DIR/d26-3 -pass -$CLEAN -$START - -log "--test 26.3 unlink multiple component recursive symlink" -rm $DIR/d26-3 -pass -$CLEAN -$START - -echo '== stripe sanity ================================= test27' -log "--test 27.1 create one stripe" -mkdir $DIR/d27 -$LSTRIPE $DIR/d27/f0 8192 0 1 -$CHECKSTAT -t file $DIR/d27/f0 -log "--test 27.2 write to one stripe file" -cp /etc/hosts $DIR/d27/f0 -pass - -log "--test 27.3 create two stripe file f01" -$LSTRIPE $DIR/d27/f01 8192 0 2 -log "--test 27.4 write to two stripe file file f01" -dd if=/dev/zero of=$DIR/d27/f01 bs=4k count=4 -pass - -log "--test 27.5 create file with default settings" -$LSTRIPE $DIR/d27/fdef 0 -1 0 -$CHECKSTAT -t file $DIR/d27/fdef -#dd if=/dev/zero of=$DIR/d27/fdef bs=4k count=4 - -log "--test 27.6 lstripe existing file (should return error)" -$LSTRIPE $DIR/d27/f12 8192 1 2 -! $LSTRIPE $DIR/d27/f12 8192 1 2 -$CHECKSTAT -t file $DIR/d27/f12 -#dd if=/dev/zero of=$DIR/d27/f12 bs=4k count=4 -pass - - -log "--test 27.7 lstripe with bad stripe size (should return error on LOV)" -$LSTRIPE $DIR/d27/fbad 100 1 2 || /bin/true -dd if=/dev/zero of=$DIR/d27/f12 bs=4k count=4 -pass -$CLEAN -$START - -log "--test 27.8 lfind " -$LFIND $DIR/d27 -pass -$CLEAN -$START - -log '== create/mknod/mkdir with bad file types ======== test28' -mkdir $DIR/d28 -$CREATETEST $DIR/d28/ct || error -pass - -log '== IT_GETATTR regression ======================== test29' -mkdir $DIR/d29 -touch $DIR/d29/foo -ls -l $DIR/d29 -MDCDIR=${MDCDIR:-/proc/fs/lustre/ldlm/ldlm/MDC_*} -LOCKCOUNTORIG=`cat $MDCDIR/lock_count` -LOCKUNUSEDCOUNTORIG=`cat $MDCDIR/lock_unused_count` -ls -l $DIR/d29 -LOCKCOUNTCURRENT=`cat $MDCDIR/lock_count` -LOCKUNUSEDCOUNTCURRENT=`cat $MDCDIR/lock_unused_count` -if [ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ] || [ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]; then - error -fi -pass -$CLEAN -$START - -log '== run binary from Lustre (execve) =============== test30' -cp `which ls` $DIR -$DIR/ls / -$CLEAN -$START - -log '== open-unlink file ============================== test31' -./openunlink $DIR/f31 $DIR/f31 || error -pass - -log '== cleanup =============================================' -rm -r $DIR/[Rdfs][1-9]* $DIR/ls - -echo '======================= finished =======================' -exit diff --git a/lustre/tests/sanityN.sh b/lustre/tests/sanityN.sh deleted file mode 100644 index 8e95654..0000000 --- a/lustre/tests/sanityN.sh +++ /dev/null @@ -1,113 +0,0 @@ -#!/bin/bash - -set -e - -PATH=$PATH:. - -CHECKSTAT=${CHECKSTAT:-"checkstat -v"} -MOUNT1=${MOUNT1:-/mnt/lustre1} -MOUNT2=${MOUNT2:-/mnt/lustre2} -export NAME=${NAME:-mount2} - -clean() { - echo -n "cln.." - sh llmountcleanup.sh > /dev/null -} - -CLEAN=${CLEAN:-clean} -start() { - echo -n "mnt.." - sh llrmount.sh > /dev/null - echo -n "done" -} -START=${START:-start} - -error () { - echo FAIL - exit 1 -} - -pass() { - echo PASS -} - -mkdir -p $MOUNT2 -mount | grep $MOUNT1 || sh llmount.sh - -echo -n "test 1: check create on 2 mtpt's..." -touch $MOUNT1/f1 -[ -f $MOUNT2/f1 ] || error -pass - -echo "test 2: check attribute updates on 2 mtpt's..." -chmod 777 $MOUNT2/f1 -$CHECKSTAT -t file -p 0777 $MOUNT1/f1 || error -pass - -echo "test 2b: check cached attribute updates on 2 mtpt's..." -touch $MOUNT1/f2b -ls -l $MOUNT2/f2b -chmod 777 $MOUNT2/f2b -$CHECKSTAT -t file -p 0777 $MOUNT1/f2b || error -pass - -echo "test 2c: check cached attribute updates on 2 mtpt's..." -touch $MOUNT1/f2c -ls -l $MOUNT2/f2c -chmod 777 $MOUNT1/f2c -$CHECKSTAT -t file -p 0777 $MOUNT2/f2c || error -pass - -echo "test 3: check after remount attribute updates on 2 mtpt's..." -chmod a-x $MOUNT2/f1 -$CLEAN -$START -$CHECKSTAT -t file -p 0666 $MOUNT1/f1 || error -pass - -echo "test 4: unlink on one mountpoint removes file on other..." -rm $MOUNT2/f1 -$CHECKSTAT -a $MOUNT1/f1 || error -pass - -echo -n "test 5: symlink on one mtpt, readlink on another..." -( cd $MOUNT1 ; ln -s this/is/good lnk ) - -[ "this/is/good" = "`perl -e 'print readlink("/mnt/lustre2/lnk");'`" ] || error -pass - -echo -n "test 6: fstat validation on multiple mount points..." -./multifstat $MOUNT1/f6 $MOUNT2/f6 -pass - -echo "test 9: remove of open file on other node..." -./openunlink $MOUNT1/f9 $MOUNT2/f9 || error -pass - -echo -n "test 10: append of file with sub-page size on multiple mounts..." -MTPT=1 -> $MOUNT2/f10 -for C in a b c d e f g h i j k l; do - MOUNT=`eval echo \\$MOUNT$MTPT` - echo -n $C >> $MOUNT/f10 - [ "$MTPT" -eq 1 ] && MTPT=2 || MTPT=1 -done -[ "`cat $MOUNT1/f10`" = "abcdefghijkl" ] && pass || error - -echo -n "test 11: write of file with sub-page size on multiple mounts..." -MTPT=1 -OFFSET=0 -> $MOUNT2/f11 -for C in a b c d e f g h i j k l; do - MOUNT=`eval echo \\$MOUNT$MTPT` - echo -n $C | dd of=$MOUNT/f11 bs=1 seek=$OFFSET count=1 - [ "$MTPT" -eq 1 ] && MTPT=2 || MTPT=1 - OFFSET=`expr $OFFSET + 1` -done -[ "`cat $MOUNT1/f11`" = "abcdefghijkl" ] && pass || error - -rm -f $MOUNT1/f[0-9]* $MOUNT1/lnk - -$CLEAN - -exit 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/statmany.c b/lustre/tests/statmany.c deleted file mode 100644 index edfa47b..0000000 --- a/lustre/tests/statmany.c +++ /dev/null @@ -1,215 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if 0 -#include -#endif -#include -#include -#include - -struct option longopts[] = { - {"ea", 0, 0, 'e'}, - {"lookup", 0, 0, 'l'}, - {"random", 0, 0, 'r'}, - {"stat", 0, 0, 's'}, - {NULL, 0, 0, 0}, -}; -char *shortopts = "ehlr:s0123456789"; - -static int usage(char *prog, FILE *out) -{ - fprintf(out, - "Usage: %s [-r rand_seed] {-s|-e|-l} filenamebase total_files iterations\n" - "-r : random seed\n" - "-s : regular stat() calls\n" - "-e : open then GET_EA ioctl\n" - "-l : lookup ioctl only\n", prog); - exit(out == stderr); -} - -#ifndef LONG_MAX -#define LONG_MAX (1 << ((8 * sizeof(long)) - 1)) -#endif - -int main(int argc, char ** argv) -{ - long i, count, iter = LONG_MAX, mode, offset; - long int start, length = LONG_MAX, last, rc = 0; - char parent[4096], *t; - char c, *prog = argv[0], *base; - int seed = 0; - int fd = -1; - - while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { - char *e; - switch (c) { - case 'r': - seed = strtoul(optarg, &e, 0); - if (*e) { - fprintf(stderr, "bad -r option %s\n", optarg); - usage(prog, stderr); - } - break; - case 'e': - case 'l': - case 's': - mode = c; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (length == LONG_MAX) - length = c - '0'; - else - length = length * 10 + (c - '0'); - break; - case 'h': - usage(prog, stdout); - case '?': - usage(prog, stderr); - } - } - - if (optind + 2 + (length == LONG_MAX) != argc) { - fprintf(stderr, "missing filenamebase, total_files, or iterations\n"); - usage(prog, stderr); - } - - base = argv[optind]; - if (strlen(base) > 4080) { - fprintf(stderr, "filenamebase too long\n"); - exit(1); - } - - if (seed == 0) { - int f = open("/dev/urandom", O_RDONLY); - - if (f < 0 || read(f, &seed, sizeof(seed)) < sizeof(seed)) - seed = time(0); - if (f > 0) - close(f); - } - - printf("using seed %u\n", seed); - srand(seed); - - count = strtoul(argv[optind + 1], NULL, 0); - if (length == LONG_MAX) { - iter = strtoul(argv[optind + 2], NULL, 0); - printf("running for %lu iterations\n", iter); - } else - printf("running for %lu seconds\n", length); - - start = last = time(0); - - t = strrchr(base, '/'); - if (t == NULL) { - strcpy(parent, "."); - offset = -1; - } else { - strncpy(parent, base, t - base); - offset = t - base + 1; - } - - if (mode == 'l') { - fd = open(parent, O_RDONLY); - if (fd < 0) { - printf("open(%s) error: %s\n", parent, - strerror(errno)); - exit(errno); - } - } - - for (i = 0; i < iter && time(0) - start < length; i++) { - char filename[4096]; - int tmp; - - tmp = random() % count; - sprintf(filename, "%s%d", base, tmp); - - if (mode == 'e') { -#if 0 - fd = open(filename, O_RDWR|O_LARGEFILE); - if (fd < 0) { - printf("open(%s) error: %s\n", filename, - strerror(errno)); - break; - } - rc = ioctl(fd, EXTN_IOC_GETEA, NULL); - if (rc < 0) { - printf("ioctl(%s) error: %s\n", filename, - strerror(errno)); - break; - } - close(fd); - break; -#endif - } else if (mode == 's') { - struct stat buf; - - rc = stat(filename, &buf); - if (rc < 0) { - printf("stat(%s) error: %s\n", filename, - strerror(errno)); - break; - } - } else if (mode == 'l') { - struct obd_ioctl_data data; - char rawbuf[8192]; - char *buf = rawbuf; - int max = sizeof(rawbuf); - - memset(&data, 0, sizeof(data)); - data.ioc_version = OBD_IOCTL_VERSION; - data.ioc_len = sizeof(data); - if (offset >= 0) - data.ioc_inlbuf1 = filename + offset; - else - data.ioc_inlbuf1 = filename; - data.ioc_inllen1 = strlen(data.ioc_inlbuf1) + 1; - - if (obd_ioctl_pack(&data, &buf, max)) { - printf("ioctl_pack failed.\n"); - break; - } - - rc = ioctl(fd, IOC_MDC_LOOKUP, buf); - if (rc < 0) { - printf("ioctl(%s) error: %s\n", filename, - strerror(errno)); - break; - } - } - if ((i % 10000) == 0) { - printf(" - stat %lu (time %ld ; total %ld ; last %ld)\n", - i, time(0), time(0) - start, time(0) - last); - last = time(0); - } - } - - if (mode == 'l') - close(fd); - - printf("total: %lu stats in %ld seconds: %f stats/second\n", i, - time(0) - start, ((float)i / (time(0) - start))); - - exit(rc); -} diff --git a/lustre/tests/statone.c b/lustre/tests/statone.c deleted file mode 100644 index 5250984..0000000 --- a/lustre/tests/statone.c +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include - -int main(int argc, char **argv) -{ - struct obd_ioctl_data data; - char rawbuf[8192], parent[4096], *buf = rawbuf, *base, *t; - int max = sizeof(rawbuf), fd, offset, rc; - - if (argc != 2) { - printf("usage: %s filename\n", argv[0]); - return 1; - } - - base = argv[1]; - t = strrchr(base, '/'); - if (!t) { - strcpy(parent, "."); - offset = -1; - } else { - strncpy(parent, base, t - base); - offset = t - base - 1; - } - - fd = open(parent, O_RDONLY); - if (fd < 0) { - printf("open(%s) error: %s\n", parent, strerror(errno)); - exit(errno); - } - - memset(&data, 0, sizeof(data)); - data.ioc_version = OBD_IOCTL_VERSION; - data.ioc_len = sizeof(data); - if (offset >= 0) - data.ioc_inlbuf1 = base + offset + 2; - else - data.ioc_inlbuf1 = base; - data.ioc_inllen1 = strlen(data.ioc_inlbuf1) + 1; - - if (obd_ioctl_pack(&data, &buf, max)) { - printf("ioctl_pack failed.\n"); - exit(1); - } - - rc = ioctl(fd, IOC_MDC_LOOKUP, buf); - if (rc < 0) { - printf("ioctl(%s/%s) error: %s\n", parent, - data.ioc_inlbuf1, strerror(errno)); - exit(errno); - } - - return 0; -} diff --git a/lustre/tests/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 08732ff..0000000 --- a/lustre/tests/tchmod.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#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) ? errno : 0; -} 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/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 774398d..0000000 --- a/lustre/tests/testreq.c +++ /dev/null @@ -1,141 +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 -#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 7f099e8..0000000 --- a/lustre/tests/toexcl.c +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -void -usage (char *argv0, int help) -{ - char *progname = strrchr(argv0, '/'); - - if (progname == NULL) - progname = argv0; - - fprintf (help ? stdout : stderr, - "Usage: %s [-e] file\n", progname); - - if (!help) - { - fprintf (stderr, " or try '-h' for help\n"); - exit (1); - } - - printf ("Create the given file with O_EXCL...\n"); - printf (" -e expect EEXIST\n"); - printf (" -h print help"); - printf (" Exit status is 0 on success, 1 on failure\n"); -} - -int main(int argc, char **argv) -{ - int rc; - int want_eexist = 0; - - while ((rc = getopt (argc, argv, "eh")) != -1) - switch (rc) - { - case 'e': - want_eexist = 1; - break; - case 'h': - usage (argv[1], 1); - return (0); - default: - usage (argv[0], 0); - } - - if (optind != argc - 1) { - usage (argv[0], 0); - return 1; - } - - rc = open(argv[optind], O_CREAT|O_EXCL, 0644); - if (rc == -1) - { - if (want_eexist && errno == EEXIST) - { - printf("open failed: %s (expected)\n", strerror(errno)); - return (0); - } - printf("open failed: %s\n", strerror(errno)); - return (1); - } else { - if (want_eexist) - { - printf("open success (expecting EEXIST).\n"); - return (1); - } - printf("open success.\n"); - return (0); - } - - return ((rc == 0) ? 0 : 1); -} 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 599bd21..0000000 --- a/lustre/tests/uml.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/bash - -config=${1-uml.xml} -LMC=${LMC-../utils/lmc} -TMP=${TMP:-/tmp} - -MDSDEV=${MDSDEV:-$TMP/mds1} -MDSSIZE=${MDSSIZE:-50000} - -OSTDEV1=${OSTDEV1:-$TMP/ost1} -OSTDEV2=${OSTDEV2:-$TMP/ost2} -OSTSIZE=${OSTSIZE:-100000} - -NETTYPE=${NETTYPE:-tcp} - -# 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=${MDSNODE:-uml1} -OSTNODES=${OSTNODES:-"uml2 uml2"} -CLIENTS=${CLIENTS:-"uml3"} - -# Single system with additional clients -#MDSNODE=uml1 -#OSTNODES="uml1 uml1" -#CLIENTS="$MDSNODE client" - -# Two systems with client on MDS, and additional clients (set up OST first) -#MDSNODE=uml1 -#OSTNODES="uml2 uml2" -#CLIENTS="$MDSNODE client" - -# Two systems with client on OST, and additional clients (set up MDS first) -#MDSNODE=uml1 -#OSTNODES="uml2 uml2" -#CLIENTS="$OSTNODES client" - -rm -f $config - -h2tcp () { - case $1 in - client) echo '\*' ;; - *) echo $1 ;; - esac -} - -h2elan () { - case $1 in - client) echo '\*' ;; - *) echo $1 | sed "s/[^0-9]*//" ;; - esac -} - -# create nodes -echo -n "adding NET for:" -for NODE in `echo $MDSNODE $OSTNODES $CLIENTS | tr -s " " "\n" | sort -u`; do - echo -n " $NODE" - ${LMC} -m $config --add net --node $NODE --nid `h2$NETTYPE $NODE` --nettype $NETTYPE || exit 1 -done - -# configure mds server -echo; echo "adding MDS on: $MDSNODE" -${LMC} -m $config --add mds --format --node $MDSNODE --mds mds1 --dev $MDSDEV --size $MDSSIZE ||exit 10 - -# configure ost -${LMC} -m $config --add lov --lov lov1 --mds mds1 --stripe_sz 65536 --stripe_cnt 1 --stripe_pattern 0 || exit 20 -COUNT=1 -echo -n "adding OST on:" -for NODE in $OSTNODES; do - eval OSTDEV=\$OSTDEV$COUNT - echo -n " $NODE" - OSTDEV=${OSTDEV:-$OSTDEV1} - ${LMC} -m $config --add ost --node $NODE --lov lov1 --dev $OSTDEV --size $OSTSIZE || exit 21 - COUNT=`expr $COUNT + 1` -done - -# create client config(s) -echo; echo -n "adding CLIENT on:" -for NODE in $CLIENTS; do - echo -n " $NODE" - ${LMC} -m $config --add mtpt --node $NODE --path /mnt/lustre --mds mds1 --lov lov1 || exit 30 -done -echo diff --git a/lustre/tests/wantedi.c b/lustre/tests/wantedi.c deleted file mode 100644 index 94ed7495..0000000 --- a/lustre/tests/wantedi.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int usage(char *prog, FILE *out) -{ - fprintf(out, - "Usage: %s \n", prog); - exit(out == stderr); -} - -#define EXTN_IOC_CREATE_INUM _IOW('f', 5, long) - -int main(int argc, char ** argv) -{ - int dirfd, wantedi, rc; - - if (argc < 2 || argc > 3) - usage(argv[0], stderr); - - dirfd = open(argv[1], O_RDONLY); - if (dirfd < 0) { - perror("open"); - exit(1); - } - - wantedi = atoi(argv[2]); - printf("Creating %s/%d with ino %d\n", argv[1], wantedi, wantedi); - - rc = ioctl(dirfd, EXTN_IOC_CREATE_INUM, wantedi); - if (rc < 0) { - perror("ioctl(EXTN_IOC_CREATE_INUM)"); - exit(2); - } - - return 0; -} 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 4775289..0000000 --- a/lustre/utils/.cvsignore +++ /dev/null @@ -1,18 +0,0 @@ -.Xrefs -config.log -config.status -configure -Makefile -Makefile.in -.deps -tags -TAGS -obdctl -lctl -lfind -lstripe -lconf -obdstat -obdio -obdbarrier -lload diff --git a/lustre/utils/Makefile.am b/lustre/utils/Makefile.am deleted file mode 100644 index d345b64..0000000 --- a/lustre/utils/Makefile.am +++ /dev/null @@ -1,20 +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) -lctl_LDADD := $(LIBREADLINE) -lptlctl -lload_LDADD := -lptlctl -sbin_PROGRAMS = lctl lfind lstripe obdio obdbarrier obdstat lload -sbin_SCRIPTS = lconf lmc llanalyze -lctl_SOURCES = parser.c obd.c lctl.c parser.h obdctl.h -lload_SOURCES = lload.c -obdio_SOURCES = obdio.c obdiolib.c obdiolib.h -obdbarrier_SOURCES = obdbarrier.c obdiolib.c obdiolib.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/automatic-reconnect-sample b/lustre/utils/automatic-reconnect-sample deleted file mode 100755 index bf9ecc4..0000000 --- a/lustre/utils/automatic-reconnect-sample +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh - -if [ -z "$1" ]; then - echo "No UUID given to Lustre upcall!" | wall - exit 1 -fi - -# FIXME: OSTHOST can't be hard-coded! -OST=$1 -OSTHOST=dev7 -LUSTRE=/home/pschwan/lustre/lustre - -while ( ! ping -c 1 -w 3 $OSTHOST ) ; do - sleep 2 -done; - -echo -n "OST $OSTHOST UUID $OST responding to pings : " -date - -$LUSTRE/utils/lctl <> /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, types -import string, os, stat, popen2, socket, time, random, fcntl, select -import re, exceptions -import xml.dom.minidom - -if sys.version[0] == '1': - from FCNTL import F_GETFL, F_SETFL -else: - from fcntl import F_GETFL, F_SETFL - -# Global parameters -MAXTCPBUF = 1048576 -DEFAULT_TCPBUF = 1048576 -# -# Maximum number of devices to search for. -# (the /dev/loop* nodes need to be created beforehand) -MAX_LOOP_DEVICES = 256 -PORTALS_DIR = '@PORTALSLOC@' - -first_cleanup_error = 0 -def cleanup_error(rc): - global first_cleanup_error - if not first_cleanup_error: - first_cleanup_error = rc - - -def usage(): - print """usage: lconf config.xml - -config.xml Lustre configuration in xml format. ---ldapurl LDAP server URL, eg. ldap://localhost ---config Cluster config name used for LDAP query ---node Load config for ---select service=nodeA,service2=nodeB U --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 - osd, mdd - 40 - mds, ost - 50 - mdc, osc - 60 - lov - 70 - mountpoint, echo_client ---lustre=src_dir Base directory of lustre sources. This parameter will cause lconf - to load modules from a source tree. ---portals=src_dir Portals source directory. If this is a relative path, then it is - assumed to be relative to lustre. - -""" - TODO = """ ---ldap server LDAP server with lustre config database ---makeldiff Translate xml source to LDIFF -This are perhaps not needed: -""" - 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._lustre_dir = '' - self._portals_dir = '' - self._minlevel = 0 - self._maxlevel = 100 - self._timeout = 0 - self._recovery_upcall = '' - self._ldapurl = '' - self._config_name = '' - self._select = {} - self._lctl_dump = '' - - 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 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 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 - - def portals_dir(self, val = None): - if val: self._portals_dir = val - return self._portals_dir - - def lustre_dir(self, val = None): - if val: self._lustre_dir = val - return self._lustre_dir - - def timeout(self, val = None): - if val: self._timeout = val - return self._timeout - - def recovery_upcall(self, val = None): - if val: self._recovery_upcall = val - return self._recovery_upcall - - def ldapurl(self, val = None): - if val: self._ldapurl = val - return self._ldapurl - - def config_name(self, val = None): - if val: self._config_name = val - return self._config_name - - def init_select(self, arg): - # arg = "service=nodeA,service2=nodeB" - list = string.split(arg, ',') - for entry in list: - srv, node = string.split(entry, '=') - self._select[srv] = node - - def select(self, srv): - if self._select.has_key(srv): - return self._select[srv] - return None - - def lctl_dump(self, val = None): - if val: self._lctl_dump = val - return self._lctl_dump - - -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 daemons, like the acceptor -class DaemonHandler: - """ Manage starting and stopping a daemon. Assumes daemon manages - it's own pid file. """ - - def __init__(self, cmd): - self.command = cmd - self.path ="" - - def start(self): - if self.running(): - log(self.command, "already running.") - if not self.path: - self.path = find_prog(self.command) - if not self.path: - panic(self.command, "not found.") - ret, out = runcmd(self.path +' '+ self.command_line()) - if ret: - raise CommandError(self.path, out, ret) - - def stop(self): - if self.running(): - pid = self.read_pidfile() - try: - log ("killing process", pid) - os.kill(pid, 15) - #time.sleep(1) # let daemon die - except OSError, e: - log("unable to kill", self.command, e) - if self.running(): - log("unable to kill", self.command) - - def running(self): - pid = self.read_pidfile() - if pid: - try: - os.kill(pid, 0) - except OSError: - self.clean_pidfile() - else: - return 1 - return 0 - - def read_pidfile(self): - try: - fp = open(self.pidfile(), 'r') - pid = int(fp.read()) - fp.close() - return pid - except IOError: - return 0 - - def clean_pidfile(self): - """ Remove a stale pidfile """ - log("removing stale pidfile:", self.pidfile()) - try: - os.unlink(self.pidfile()) - except OSError, e: - log(self.pidfile(), e) - -class AcceptorHandler(DaemonHandler): - def __init__(self, port, net_type, send_mem, recv_mem, irq_aff, nid_xchg): - DaemonHandler.__init__(self, "acceptor") - self.port = port - self.flags = '' - self.send_mem = send_mem - self.recv_mem = recv_mem - - if net_type == 'toe': - self.flags = self.flags + ' -N 4' - if irq_aff: - self.flags = self.flags + ' -i' - if nid_xchg: - self.flags = self.flags + ' -x' - - def pidfile(self): - return "/var/run/%s-%d.pid" % (self.command, self.port) - - def command_line(self): - return string.join(map(str,('-s', self.send_mem, '-r', self.recv_mem, self.flags, self.port))) - -acceptors = {} - -# start the acceptors -def run_acceptors(): - for port in acceptors.keys(): - daemon = acceptors[port] - if not daemon.running(): - daemon.start() - -def stop_acceptor(port): - if acceptors.has_key(port): - daemon = acceptors[port] - if daemon.running(): - daemon.stop() - - -# ============================================================ -# 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) - self.save_file = '' - if not self.lctl: - if config.noexec(): - debug('! lctl not found') - self.lctl = 'lctl' - else: - raise CommandError('lctl', "unable to find lctl binary.") - - def use_save_file(self, file): - self.save_file = file - - def set_nonblock(self, fd): - fl = fcntl.fcntl(fd, F_GETFL) - fcntl.fcntl(fd, F_SETFL, fl | os.O_NDELAY) - - 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 - """ - cmd_line = self.lctl - if self.save_file: - cmds = '\n dump ' + self.save_file + cmds - - debug("+", cmd_line, cmds) - if config.noexec(): return (0, []) - - child = popen2.Popen3(cmd_line, 1) # Capture stdout and stderr from command - child.tochild.write(cmds + "\n") - child.tochild.close() - - # From "Python Cookbook" from O'Reilly - outfile = child.fromchild - outfd = outfile.fileno() - self.set_nonblock(outfd) - errfile = child.childerr - errfd = errfile.fileno() - self.set_nonblock(errfd) - - outdata = errdata = '' - outeof = erreof = 0 - while 1: - ready = select.select([outfd,errfd],[],[]) # Wait for input - if outfd in ready[0]: - outchunk = outfile.read() - if outchunk == '': outeof = 1 - outdata = outdata + outchunk - if errfd in ready[0]: - errchunk = errfile.read() - if errchunk == '': erreof = 1 - errdata = errdata + errchunk - if outeof and erreof: break - # end of "borrowed" code - - ret = child.wait() - if os.WIFEXITED(ret): - rc = os.WEXITSTATUS(ret) - else: - rc = 0 - if rc or len(errdata): - raise CommandError(self.lctl, errdata, rc) - return rc, outdata - - 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 - quit """ % (net, nid) - self.run(cmds) - - # create a new connection - def connect(self, srv): - cmds = "\n add_uuid %s %s %s" % (srv.uuid, srv.nid, srv.net_type) - if srv.net_type in ('tcp', 'toe') and not config.lctl_dump(): - flags = '' - if srv.irq_affinity: - flags = flags + 'i' - if srv.nid_exchange: - flags = flags + 'x' - cmds = """%s - network %s - send_mem %d - recv_mem %d - connect %s %d %s""" % (cmds, srv.net_type, - srv.send_mem, - srv.recv_mem, - srv.hostaddr, srv.port, flags ) - - cmds = cmds + "\n quit" - 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 %s - add_route %s %s - quit """ % (net, - uuid, tgt, net, - 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 - 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 %s - detach - 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 runcmd(cmd): - 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) - -def run(*args): - cmd = string.join(map(str,args)) - return runcmd(cmd) - -# 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); - if config.portals_dir(): - syspath.insert(0, os.path.join(config.portals_dir()+'/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(dev, devsize, fstype): - block_cnt = '' - if devsize: - # devsize is in 1k, and fs block count is in 4k - block_cnt = devsize/4 - - if(fstype in ('ext3', 'extN')): - mkfs = 'mkfs.ext2 -j -b 4096 -F ' - elif (fstype == 'reiserfs'): - mkfs = 'mkreiserfs -ff' - else: - print 'unsupported fs type: ', fstype - - (ret, out) = run (mkfs, dev, block_cnt) - 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): - if size < 8000: - panic(file, "size must be larger than 8MB, currently set to:", size) - (ret, out) = run("dd if=/dev/zero bs=1k count=0 seek=%d of=%s" %(size, - file)) - if ret: - panic("Unable to create backing store:", 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(dev, size, fstype) - -# 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_nid(net_type, wildcard): - """Return the local nid. First look for an elan interface, - then use the local address. """ - local = "" - if os.access('/proc/elan/device0/position', os.R_OK): - local = get_local_address('elan', '*') - else: - local = get_local_address(net_type, wildcard) - return local - -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 - if config.lctl_dump(): - return 0 - try: - out = lctl.device_list() - for s in out: - if uuid == string.split(s)[4]: - return 1 - except CommandError, e: - e.dump() - return 0 - -def is_network_prepared(): - """If the PTLRPC device exists, then assumet that all networking - has been configured""" - if config.lctl_dump(): - return 0 - try: - out = lctl.device_list() - for s in out: - if 'RPCDEV_UUID' == string.split(s)[4]: - return 1 - except CommandError, e: - e.dump() - return 0 - - -def fs_is_mounted(path): - """Return true if path is a mounted lustre filesystem""" - try: - fp = open('/proc/mounts') - lines = fp.readlines() - fp.close() - for l in lines: - a = string.split(l) - if a[1] == path and a[2] == 'lustre_lite': - return 1 - except IOError, e: - log(e) - 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, db): - self.db = db - self.module_name = module_name - self.name = self.db.getName() - self.uuid = self.db.getUUID() - 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 cleanup(self): - """ default cleanup, used for most modules """ - self.info() - 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_portals_module(self, dev_dir, modname): - """Append a module to list of modules to load.""" - self.kmodule_list.append((config.portals_dir(), dev_dir, modname)) - - def add_lustre_module(self, dev_dir, modname): - """Append a module to list of modules to load.""" - self.kmodule_list.append((config.lustre_dir(), 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 src_dir, 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 src_dir: - module = find_module(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 src_dir, 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,db): - Module.__init__(self, 'NETWORK', db) - self.net_type = self.db.get_val('nettype') - self.nid = self.db.get_val('nid', '*') - self.port = self.db.get_val_int('port', 0) - self.send_mem = self.db.get_val_int('sendmem', DEFAULT_TCPBUF) - self.recv_mem = self.db.get_val_int('recvmem', DEFAULT_TCPBUF) - self.irq_affinity = self.db.get_val_int('irqaffinity', 0) - self.nid_exchange = self.db.get_val_int('nidexchange', 0) - - if '*' in self.nid: - self.nid = get_local_nid(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.hostaddr = self.db.get_val('hostaddr', self.nid) - if '*' in self.hostaddr: - self.hostaddr = get_local_address(self.net_type, self.hostaddr) - if not self.nid: - panic("unable to set nid for", self.net_type, self.hostaddr) - debug("hostaddr:", self.hostaddr) - # debug ( "hostaddr ", self.hostaddr, "net_type", self.net_type) - - self.add_portals_module("linux/oslib", 'portals') - if node_needs_router(): - self.add_portals_module("linux/router", 'kptlrouter') - if self.net_type == 'tcp': - self.add_portals_module("linux/socknal", 'ksocknal') - if self.net_type == 'toe': - self.add_portals_module("/linux/toenal", 'ktoenal') - if self.net_type == 'elan': - self.add_portals_module("/linux/rqswnal", 'kqswnal') - if self.net_type == 'gm': - self.add_portals_module("/linux/gmnal", 'kgmnal') - self.add_lustre_module('obdclass', 'obdclass') - - def prepare(self): - if is_network_prepared(): - return - self.info(self.net_type, self.nid, self.port) - lctl.network(self.net_type, self.nid) - - def cleanup(self): - self.info(self.net_type, self.nid, self.port) - if self.net_type in ('tcp', 'toe'): - stop_acceptor(self.port) - try: - lctl.disconnectAll(self.net_type) - except CommandError, e: - print "disconnectAll failed: ", self.name - e.dump() - cleanup_error(e.rc) - -class Router(Module): - def __init__(self,db): - Module.__init__(self, 'ROUTER', db) - def prepare(self): - if is_network_prepared(): - return - self.info() - for net_type, gw, lo, hi in self.db.get_route_tbl(): - lctl.add_route(net_type, gw, lo, hi) - if net_type in ('tcp', 'toe') and local_net_type(net_type) and hi == '': - srvdb = self.db.nid2server(lo, net_type) - - if not srvdb: - panic("no server for nid", lo) - else: - srv = Network(srvdb) - lctl.connect(srv) - def cleanup(self): - for net_type, gw, lo, hi in self.db.get_route_tbl(): - if net_type in ('tcp', 'toe') and local_net_type(net_type) and hi == '': - srvdb = self.db.nid2server(lo, net_type) - if not srvdb: - panic("no server for nid", lo) - else: - srv = Network(srvdb) - 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(net_type, gw, lo, hi) - except CommandError, e: - print "del_route failed: ", self.name - e.dump() - cleanup_error(e.rc) - -class LDLM(Module): - def __init__(self,db): - Module.__init__(self, 'LDLM', db) - self.add_lustre_module('ldlm', 'ldlm') - def prepare(self): - if is_prepared(self.uuid): - return - self.info() - lctl.newdev(attach="ldlm %s %s" % (self.name, self.uuid)) - def cleanup(self): - if is_prepared(self.uuid): - Module.cleanup(self) - -class PTLRPC(Module): - def __init__(self,db): - Module.__init__(self, 'PTLRPC', db) - self.add_lustre_module('ptlrpc', 'ptlrpc') - def prepare(self): - if is_prepared(self.uuid): - return - self.info() - lctl.newdev(attach="ptlrpc %s %s" % (self.name, self.uuid)) - def cleanup(self): - if is_prepared(self.uuid): - Module.cleanup(self) - -class LOV(Module): - def __init__(self,db): - Module.__init__(self, 'LOV', db) - self.add_lustre_module('mdc', 'mdc') - self.add_lustre_module('lov', 'lov') - self.mds_uuid = self.db.get_first_ref('mds') - mds= self.db.lookup(self.mds_uuid) - self.mds_name = mds.getName() - self.stripe_sz = self.db.get_val_int('stripesize', 65536) - self.stripe_off = self.db.get_val_int('stripeoffset', 0) - self.pattern = self.db.get_val_int('stripepattern', 0) - self.devlist = self.db.get_refs('obd') - self.stripe_cnt = self.db.get_val_int('stripecount', len(self.devlist)) - self.osclist = [] - self.mdc_uudi = '' - for obd_uuid in self.devlist: - obd = self.db.lookup(obd_uuid) - osc = get_osc(obd, self.name) - if osc: - self.osclist.append(osc) - else: - panic('osc not found:', obd_uuid) - - def prepare(self): - if is_prepared(self.uuid): - return - for osc in self.osclist: - try: - # Ignore connection failures, because the LOV will DTRT with - # an unconnected OSC. - osc.prepare(ignore_connect_failure=1) - except CommandError: - print "Error preparing OSC %s (inactive)\n" % osc.uuid - self.mdc_uuid = prepare_mdc(self.db, self.name, 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" % (self.mdc_uuid)) - - def cleanup(self): - if is_prepared(self.uuid): - Module.cleanup(self) - for osc in self.osclist: - osc.cleanup() - cleanup_mdc(self.db, self.name, self.mds_uuid) - - def load_module(self): - for osc in self.osclist: - osc.load_module() - break - Module.load_module(self) - - def cleanup_module(self): - Module.cleanup_module(self) - for osc in self.osclist: - osc.cleanup_module() - break - -class LOVConfig(Module): - def __init__(self,db): - Module.__init__(self, 'LOVConfig', db) - - self.lov_uuid = self.db.get_first_ref('lov') - l = self.db.lookup(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 MDSDEV(Module): - def __init__(self,db): - Module.__init__(self, 'MDSDEV', db) - self.devpath = self.db.get_val('devpath','') - self.size = self.db.get_val_int('devsize', 0) - self.fstype = self.db.get_val('fstype', '') - # overwrite the orignal MDSDEV name and uuid with the MDS name and uuid - target_uuid = self.db.get_first_ref('target') - mds = self.db.lookup(target_uuid) - self.name = mds.getName() - self.lovconfig_uuids = mds.get_refs('lovconfig') - # FIXME: if fstype not set, then determine based on kernel version - self.format = self.db.get_val('autoformat', "no") - - active_uuid = mds.get_active_target() - if not active_uuid: - panic("No target device found:", target_uuid) - if active_uuid == self.uuid: - self.active = 1 - else: - self.active = 0 - self.target_dev_uuid = self.uuid - self.uuid = target_uuid - # modules - if self.fstype == 'extN': - self.add_lustre_module('extN', 'extN') - self.add_lustre_module('mds', 'mds') - if self.fstype: - self.add_lustre_module('obdclass', 'fsfilt_%s' % (self.fstype)) - - def load_module(self): - if self.active: - Module.load_module(self) - - def prepare(self): - if is_prepared(self.uuid): - return - if not self.active: - debug(self.uuid, "not active") - return - self.info(self.devpath, self.fstype, self.format) - run_acceptors() - blkdev = block_dev(self.devpath, 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)) - for uuid in self.lovconfig_uuids: - db = self.db.lookup(uuid) - lovconfig = LOVConfig(db) - lovconfig.prepare() - - 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 is_prepared(self.uuid): - Module.cleanup(self) - clean_loop(self.devpath) - -class OSD(Module): - def __init__(self, db): - Module.__init__(self, 'OSD', db) - self.osdtype = self.db.get_val('osdtype') - self.devpath = self.db.get_val('devpath', '') - self.size = self.db.get_val_int('devsize', 0) - self.fstype = self.db.get_val('fstype', '') - target_uuid = self.db.get_first_ref('target') - ost = self.db.lookup(target_uuid) - self.name = ost.getName() - # FIXME: if fstype not set, then determine based on kernel version - self.format = self.db.get_val('autoformat', 'yes') - if self.fstype == 'extN': - self.add_lustre_module('extN', 'extN') - - active_uuid = ost.get_active_target() - if not active_uuid: - panic("No target device found:", target_uuid) - if active_uuid == self.uuid: - self.active = 1 - else: - self.active = 0 - self.target_dev_uuid = self.uuid - self.uuid = target_uuid - # modules - self.add_lustre_module('ost', 'ost') - self.add_lustre_module(self.osdtype, self.osdtype) - if self.fstype: - self.add_lustre_module('obdclass' , 'fsfilt_%s' % (self.fstype)) - - def load_module(self): - if self.active: - Module.load_module(self) - - # 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 - if not self.active: - debug(self.uuid, "not active") - return - self.info(self.osdtype, self.devpath, self.size, self.fstype, self.format) - run_acceptors() - if self.osdtype == 'obdecho': - blkdev = '' - else: - blkdev = block_dev(self.devpath, self.size, self.fstype, self.format) - lctl.newdev(attach="%s %s %s" % (self.osdtype, self.name, self.uuid), - setup ="%s %s" %(blkdev, self.fstype)) - if not is_prepared('OSS_UUID'): - lctl.newdev(attach="ost %s %s" % ('OSS', 'OSS_UUID'), - setup ="") - - def cleanup(self): - if is_prepared('OSS_UUID'): - try: - lctl.cleanup("OSS", "OSS_UUID") - except CommandError, e: - print "cleanup failed: ", self.name - e.dump() - cleanup_error(e.rc) - if is_prepared(self.uuid): - Module.cleanup(self) - if not self.osdtype == 'obdecho': - clean_loop(self.devpath) - -# Generic client module, used by OSC and MDC -class Client(Module): - def __init__(self, tgtdb, module, owner): - self.target_name = tgtdb.getName() - self.target_uuid = tgtdb.getUUID() - self.db = tgtdb - - self.tgt_dev_uuid = tgtdb.get_active_target() - if not self.tgt_dev_uuid: - panic("No target device found for target:", self.target_name) - - self.kmodule_list = [] - self._server = None - self._connected = 0 - - self.module = module - self.module_name = string.upper(module) - self.name = '%s_%s_%s' % (self.module_name, owner, self.target_name) - self.uuid = '%05x%05x_%.14s_%05x%05x' % (int(random.random() * 1048576), - int(random.random() * 1048576),self.name, - int(random.random() * 1048576), - int(random.random() * 1048576)) - self.uuid = self.uuid[0:36] - self.lookup_server(self.tgt_dev_uuid) - self.add_lustre_module(module, module) - - def lookup_server(self, srv_uuid): - """ Lookup a server's network information """ - self._server_nets = self.db.get_ost_net(srv_uuid) - if len(self._server_nets) == 0: - panic ("Unable to find a server for:", srv_uuid) - - def get_servers(self): - return self._server_nets - - def prepare(self, ignore_connect_failure = 0): - if is_prepared(self.uuid): - return - self.info(self.target_uuid) - try: - srv = local_net(self.get_servers()) - if srv: - lctl.connect(srv) - else: - srv, r = find_route(self.get_servers()) - if srv: - lctl.add_route_host(r[0], srv.uuid, r[1], r[2]) - else: - panic ("no route to", self.target_uuid) - except CommandError: - if (ignore_connect_failure == 0): - pass - if srv: - lctl.newdev(attach="%s %s %s" % (self.module, self.name, self.uuid), - setup ="%s %s" %(self.target_uuid, srv.uuid)) - - def cleanup(self): - Module.cleanup(self) - srv = local_net(self.get_servers()) - if 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) - else: - self.info(self.target_uuid) - srv, r = find_route(self.get_servers()) - if srv: - 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) - - - -class MDC(Client): - def __init__(self, db, owner): - Client.__init__(self, db, 'mdc', owner) - -class OSC(Client): - def __init__(self, db, owner): - Client.__init__(self, db, 'osc', owner) - - -class COBD(Module): - def __init__(self, db): - Module.__init__(self, 'COBD', db) - self.real_uuid = self.db.get_first_ref('realobd') - self.cache_uuid = self.db.get_first_ref('cacheobd') - self.add_lustre_module('cobd' , 'cobd') - - # 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.real_uuid, self.cache_uuid) - lctl.newdev(attach="cobd %s %s" % (self.name, self.uuid), - setup ="%s %s" %(self.real_uuid, self.cache_uuid)) - - -# virtual interface for OSC and LOV -class VOSC(Module): - def __init__(self,db, owner): - Module.__init__(self, 'VOSC', db) - if db.get_class() == 'lov': - self.osc = LOV(db) - else: - self.osc = get_osc(db, owner) - def get_uuid(self): - return self.osc.uuid - 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() - def need_mdc(self): - return self.db.get_class() != 'lov' - def get_mdc_uuid(self): - if self.db.get_class() == 'lov': - return self.osc.mdc_uuid - return '' - - -class ECHO_CLIENT(Module): - def __init__(self,db): - Module.__init__(self, 'ECHO_CLIENT', db) - self.add_lustre_module('obdecho', 'obdecho') - self.obd_uuid = self.db.get_first_ref('obd') - obd = self.db.lookup(self.obd_uuid) - self.osc = VOSC(obd, self.name) - - def prepare(self): - if is_prepared(self.uuid): - return - self.osc.prepare() # XXX This is so cheating. -p - self.info(self.obd_uuid) - - lctl.newdev(attach="echo_client %s %s" % (self.name, self.uuid), - setup = self.osc.get_uuid()) - - def cleanup(self): - if is_prepared(self.uuid): - Module.cleanup(self) - 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,db): - Module.__init__(self, 'MTPT', db) - self.path = self.db.get_val('path') - self.mds_uuid = self.db.get_first_ref('mds') - self.obd_uuid = self.db.get_first_ref('obd') - obd = self.db.lookup(self.obd_uuid) - self.vosc = VOSC(obd, self.name) - if self.vosc.need_mdc(): - self.add_lustre_module('mdc', 'mdc') - self.add_lustre_module('llite', 'llite') - - - def prepare(self): - self.vosc.prepare() - if self.vosc.need_mdc(): - mdc_uuid = prepare_mdc(self.db, self.name, self.mds_uuid) - else: - mdc_uuid = self.vosc.get_mdc_uuid() - if not mdc_uuid: - panic("Unable to determine MDC UUID. Probably need to cleanup before re-mounting.") - self.info(self.path, self.mds_uuid, self.obd_uuid) - cmd = "mount -t lustre_lite -o osc=%s,mdc=%s none %s" % \ - (self.vosc.get_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.obd_uuid) - if fs_is_mounted(self.path): - if config.force(): - (rc, out) = run("umount", "-f", self.path) - else: - (rc, out) = run("umount", self.path) - if rc: - raise CommandError('umount', out, rc) - - if fs_is_mounted(self.path): - panic("fs is still mounted:", self.path) - - self.vosc.cleanup() - if self.vosc.need_mdc(): - cleanup_mdc(self.db, self.name, self.mds_uuid) - - def load_module(self): - self.vosc.load_module() - Module.load_module(self) - def cleanup_module(self): - Module.cleanup_module(self) - self.vosc.cleanup_module() - - -# ============================================================ -# XML processing and query - -class LustreDB: - def lookup(self, uuid): - """ lookup returns a new LustreDB instance""" - return self._lookup_by_uuid(uuid) - - def lookup_name(self, name, class_name = ""): - """ lookup returns a new LustreDB instance""" - return self._lookup_by_name(name, class_name) - - def lookup_class(self, class_name): - """ lookup returns a new LustreDB instance""" - return self._lookup_by_class(class_name) - - def get_val(self, tag, default=None): - v = self._get_val(tag) - if v: - return v - if default != None: - return default - debug("LustreDB", self.getName(), " no value for:", tag) - return None - - def get_class(self): - return self._get_class() - - def get_val_int(self, tag, default=0): - str = self._get_val(tag) - try: - if str: - return int(str) - return default - except ValueError: - panic("text value is not integer:", str) - - def get_first_ref(self, tag): - """ Get the first uuidref of the type TAG. Only - one is expected. Returns the uuid.""" - uuids = self._get_refs(tag) - if len(uuids) > 0: - return uuids[0] - return None - - def get_refs(self, tag): - """ Get all the refs of type TAG. Returns list of uuids. """ - uuids = self._get_refs(tag) - return uuids - - def get_all_refs(self): - """ Get all the refs. Returns list of uuids. """ - uuids = self._get_all_refs() - return uuids - - def get_ost_net(self, osd_uuid): - srv_list = [] - if not osd_uuid: - return srv_list - osd = self.lookup(osd_uuid) - node_uuid = osd.get_first_ref('node') - node = self.lookup(node_uuid) - if not node: - panic("unable to find node for osd_uuid:", osd_uuid, - " node_ref:", node_uuid) - for net_uuid in node.get_networks(): - db = node.lookup(net_uuid) - srv_list.append(Network(db)) - return srv_list - - def nid2server(self, nid, net_type): - netlist = self.lookup_class('network') - for net_db in netlist: - if net_db.get_val('nid') == nid and net_db.get_val('nettype') == net_type: - return net_db - return None - - # the tag name is the service type - # fixme: this should do some checks to make sure the dom_node is a service - # - # determine what "level" a particular node is at. - - # the order of iniitailization is based on level. - def getServiceLevel(self): - type = self.get_class() - ret=0; - if type in ('network',): - ret = 5 - elif type in ('routetbl',): - ret = 6 - elif type in ('ptlrpc',): - ret = 7 - elif type in ('device', 'ldlm'): - ret = 20 - elif type in ('osd', 'mdd', 'cobd'): - ret = 30 - elif type in ('mdsdev','ost'): - ret = 40 - elif type in ('mdc','osc'): - ret = 50 - elif type in ('lov',): - ret = 60 - elif type in ('mountpoint', 'echoclient'): - 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, db_object),] - def getServices(self): - list = [] - for ref_class, ref_uuid in self.get_all_refs(): - servdb = self.lookup(ref_uuid) - if servdb: - level = servdb.getServiceLevel() - if level > 0: - list.append((level, servdb)) - else: - panic('service not found: ' + ref_uuid) - - list.sort() - return list - - # Find the target_device for target on a node - # node->profiles->device_refs->target - def get_target_device(self, target_uuid, node_name): - node_db = self.lookup_name(node_name) - if not node_db: - return None - prof_list = node_db.get_refs('profile') - for prof_uuid in prof_list: - prof_db = node_db.lookup(prof_uuid) - ref_list = prof_db.get_all_refs() - for ref in ref_list: - dev = self.lookup(ref[1]) - if dev and dev.get_first_ref('target') == target_uuid: - return ref[1] - return None - - def get_active_target(self): - target_uuid = self.getUUID() - target_name = self.getName() - node_name = config.select(target_name) - if node_name: - tgt_dev_uuid = self.get_target_device(target_uuid, node_name) - else: - tgt_dev_uuid = self.get_first_ref('active') - return tgt_dev_uuid - - - # get all network uuids for this node - def get_networks(self): - ret = [] - prof_list = self.get_refs('profile') - for prof_uuid in prof_list: - prof_db = self.lookup(prof_uuid) - net_list = prof_db.get_refs('network') - #debug("get_networks():", prof_uuid, net_list) - for net_uuid in net_list: - ret.append(net_uuid) - return ret - -class LustreDB_XML(LustreDB): - def __init__(self, dom, root_node): - # init xmlfile - self.dom_node = dom - self.root_node = root_node - - def xmltext(self, dom_node, tag): - list = dom_node.getElementsByTagName(tag) - if len(list) > 0: - dom_node = list[0] - dom_node.normalize() - if dom_node.firstChild: - txt = string.strip(dom_node.firstChild.data) - if txt: - return txt - - def xmlattr(self, dom_node, attr): - return dom_node.getAttribute(attr) - - def _get_val(self, tag): - """a value could be an attribute of the current node - or the text value in a child node""" - ret = self.xmlattr(self.dom_node, tag) - if not ret: - ret = self.xmltext(self.dom_node, tag) - return ret - - def _get_class(self): - return self.dom_node.nodeName - - # - # [(ref_class, ref_uuid),] - def _get_all_refs(self): - list = [] - for n in self.dom_node.childNodes: - if n.nodeType == n.ELEMENT_NODE: - ref_uuid = self.xml_get_ref(n) - ref_class = n.nodeName - list.append((ref_class, ref_uuid)) - - list.sort() - return list - - def _get_refs(self, tag): - """ Get all the refs of type TAG. Returns list of uuids. """ - uuids = [] - refname = '%s_ref' % tag - reflist = self.dom_node.getElementsByTagName(refname) - for r in reflist: - uuids.append(self.xml_get_ref(r)) - return uuids - - def xmllookup_by_uuid(self, dom_node, uuid): - for n in dom_node.childNodes: - if n.nodeType == n.ELEMENT_NODE: - if self.xml_get_uuid(n) == uuid: - return n - else: - n = self.xmllookup_by_uuid(n, uuid) - if n: return n - return None - - def _lookup_by_uuid(self, uuid): - dom = self. xmllookup_by_uuid(self.root_node, uuid) - if dom: - return LustreDB_XML(dom, self.root_node) - - def xmllookup_by_name(self, dom_node, name): - for n in dom_node.childNodes: - if n.nodeType == n.ELEMENT_NODE: - if self.xml_get_name(n) == name: - return n - else: - n = self.xmllookup_by_name(n, name) - if n: return n - return None - - def _lookup_by_name(self, name, class_name): - dom = self.xmllookup_by_name(self.root_node, name) - if dom: - return LustreDB_XML(dom, self.root_node) - - def xmllookup_by_class(self, dom_node, class_name): - return dom_node.getElementsByTagName(class_name) - - def _lookup_by_class(self, class_name): - ret = [] - domlist = self.xmllookup_by_class(self.root_node, class_name) - for node in domlist: - ret.append(LustreDB_XML(node, self.root_node)) - return ret - - def xml_get_name(self, n): - return n.getAttribute('name') - - def getName(self): - return self.xml_get_name(self.dom_node) - - def xml_get_ref(self, n): - return n.getAttribute('uuidref') - - def xml_get_uuid(self, dom_node): - return dom_node.getAttribute('uuid') - - def getUUID(self): - return self.xml_get_uuid(self.dom_node) - - def get_routes(self, type, gw): - """ Return the routes as a list of tuples of the form: - [(type, gw, lo, hi),]""" - res = [] - tbl = self.dom_node.getElementsByTagName('routetbl') - for t in tbl: - routes = t.getElementsByTagName('route') - for r in routes: - net_type = self.xmlattr(r, 'type') - if type != net_type: - lo = self.xmlattr(r, 'lo') - hi = self.xmlattr(r, 'hi') - res.append((type, gw, lo, hi)) - return res - - def get_route_tbl(self): - ret = [] - for r in self.dom_node.getElementsByTagName('route'): - net_type = self.xmlattr(r, 'type') - gw = self.xmlattr(r, 'gw') - lo = self.xmlattr(r, 'lo') - hi = self.xmlattr(r, 'hi') - ret.append((net_type, gw, lo, hi)) - return ret - - -# ================================================================ -# LDAP Support -class LustreDB_LDAP(LustreDB): - def __init__(self, name, attrs, - base = "fs=lustre", - parent = None, - url = "ldap://localhost", - user = "cn=Manager, fs=lustre", - pw = "secret" - ): - self._name = name - self._attrs = attrs - self._base = base - self._parent = parent - self._url = url - self._user = user - self._pw = pw - if parent: - self.l = parent.l - self._base = parent._base - else: - self.open() - - def open(self): - import ldap - try: - self.l = ldap.initialize(self._url) - # Set LDAP protocol version used - self.l.protocol_version=ldap.VERSION3 - # user and pw only needed if modifying db - self.l.bind_s("", "", ldap.AUTH_SIMPLE); - except ldap.LDAPError, e: - panic(e) - # FIXME, do something useful here - - def close(self): - self.l.unbind_s() - - def ldap_search(self, filter): - """Return list of uuids matching the filter.""" - import ldap - dn = self._base - ret = [] - uuids = [] - try: - for name, attrs in self.l.search_s(dn, ldap.SCOPE_ONELEVEL, - filter, ["uuid"]): - for v in attrs['uuid']: - uuids.append(v) - except ldap.NO_SUCH_OBJECT, e: - pass - except ldap.LDAPError, e: - print e # FIXME: die here? - if len(uuids) > 0: - for uuid in uuids: - ret.append(self._lookup_by_uuid(uuid)) - return ret - - def _lookup_by_name(self, name, class_name): - list = self.ldap_search("lustreName=%s" %(name)) - if len(list) == 1: - return list[0] - return [] - - def _lookup_by_class(self, class_name): - return self.ldap_search("objectclass=%s" %(string.upper(class_name))) - - def _lookup_by_uuid(self, uuid): - import ldap - dn = "uuid=%s,%s" % (uuid, self._base) - ret = None - try: - for name, attrs in self.l.search_s(dn, ldap.SCOPE_BASE, - "objectclass=*"): - ret = LustreDB_LDAP(name, attrs, parent = self) - - except ldap.NO_SUCH_OBJECT, e: - debug("NO_SUCH_OBJECT:", uuid) - pass # just return empty list - except ldap.LDAPError, e: - print e # FIXME: die here? - return ret - - - def _get_val(self, k): - ret = None - if self._attrs.has_key(k): - v = self._attrs[k] - if type(v) == types.ListType: - ret = str(v[0]) - else: - ret = str(v) - return ret - - def _get_class(self): - return string.lower(self._attrs['objectClass'][0]) - - # - # [(ref_class, ref_uuid),] - def _get_all_refs(self): - list = [] - for k in self._attrs.keys(): - if re.search('.*Ref', k): - for uuid in self._attrs[k]: - list.append((k, uuid)) - return list - - def _get_refs(self, tag): - """ Get all the refs of type TAG. Returns list of uuids. """ - uuids = [] - refname = '%sRef' % tag - if self._attrs.has_key(refname): - return self._attrs[refname] - return [] - - def getName(self): - return self._get_val('lustreName') - - def getUUID(self): - return self._get_val('uuid') - - def get_route_tbl(self): - return [] - -############################################################ -# MDC UUID hack - -# FIXME: clean this mess up! -# -# OSC is no longer in the xml, so we have to fake it. -# this is getting ugly and begging for another refactoring -def get_osc(ost_db, owner): - osc = OSC(ost_db, owner) - return osc - -def get_mdc(db, owner, mds_uuid): - mds_db = db.lookup(mds_uuid); - if not mds_db: - panic("no mds:", mds_uuid) - mdc = MDC(mds_db, owner) - return mdc - -def prepare_mdc(db, owner, mds_uuid): - mdc = get_mdc(db, owner, mds_uuid) - mdc.prepare() - return mdc.uuid - -def cleanup_mdc(db, owner, mds_uuid): - mdc = get_mdc(db, owner, mds_uuid) - mdc.cleanup() - - -############################################################ -# routing ("rooting") -# -routes = [] -local_node = [] -router_flag = 0 - -def add_local_interfaces(node_db): - global local_node - for netuuid in node_db.get_networks(): - net = node_db.lookup(netuuid) - srv = Network(net) - debug("add_local", netuuid) - local_node.append((srv.net_type, srv.nid)) - if acceptors.has_key(srv.port): - panic("duplicate port:", srv.port) - if srv.net_type in ('tcp', 'toe'): - acceptors[srv.port] = AcceptorHandler(srv.port, srv.net_type, - srv.send_mem, srv.recv_mem, - srv.irq_affinity, - srv.nid_exchange) - -def node_needs_router(): - return router_flag - -def init_route_config(lustre): - """ Scan the lustre config looking for routers. Build list of - routes. """ - global routes, router_flag - routes = [] - list = lustre.lookup_class('node') - for node_db in list: - if node_db.get_val_int('router', 0): - router_flag = 1 - #debug("init_route_config: found router", node_db.getName()) - for (local_type, local_nid) in local_node: - #debug("init_route_config:", local_type, local_nid) - gw = None - for netuuid in node_db.get_networks(): - db = node_db.lookup(netuuid) - if local_type == db.get_val('nettype'): - gw = db.get_val('nid') - break - #debug("init_route_config: gw is", gw) - if not gw: - continue - for route in node_db.get_routes(local_type, gw): - routes.append(route) - debug("init_route_config routes:", routes) - - -def local_net(srv_list): - global local_node - for iface in local_node: - for srv in srv_list: - #debug("local_net a:", srv.net_type, "b:", iface[0]) - if srv.net_type == iface[0]: - return srv - return None - -def local_net_type(net_type): - global local_node - for iface in local_node: - if net_type == iface[0]: - return 1 - return 0 - -def find_route(srv_list): - global local_node, routes - frm_type = local_node[0][0] - for srv in srv_list: - #debug("find_route: srv:", srv.hostaddr, "type: ", srv.net_type) - to_type = srv.net_type - to = srv.hostaddr - #debug ('looking for route to', to_type, to) - for r in routes: - #debug("find_route: ", r) - if r[2] == to: - return srv, r - return None,None - - -############################################################ -# lconf level logic -# Start a service. -def newService(db): - type = db.get_class() - debug('Service:', type, db.getName(), db.getUUID()) - n = None - if type == 'ldlm': - n = LDLM(db) - elif type == 'ptlrpc': - n = PTLRPC(db) - elif type == 'lov': - n = LOV(db) - elif type == 'network': - n = Network(db) - elif type == 'routetbl': - n = Router(db) - elif type == 'osd': - n = OSD(db) - elif type == 'cobd': - n = COBD(db) - elif type == 'mdsdev': - n = MDSDEV(db) - elif type == 'mountpoint': - n = Mountpoint(db) - elif type == 'echoclient': - n = ECHO_CLIENT(db) - else: - panic ("unknown service type:", type) - return n - -# -# 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 for_each_profile(db, prof_list, operation): - for prof_uuid in prof_list: - prof_db = db.lookup(prof_uuid) - if not prof_db: - panic("profile:", profile, "not found.") - services = prof_db.getServices() - operation(services) - -def doSetup(services): - if config.nosetup(): - return - for s in services: - n = newService(s[1]) - n.prepare() - -def doModules(services): - if config.nomod(): - return - for s in services: - n = newService(s[1]) - n.load_module() - -def doCleanup(services): - if config.nosetup(): - return - services.reverse() - for s in services: - n = newService(s[1]) - n.cleanup() - -def doUnloadModules(services): - if config.nomod(): - return - services.reverse() - for s in services: - n = newService(s[1]) - n.cleanup_module() - -# -# Load profile for -def doHost(lustreDB, hosts): - global routes - global router_flag - node_db = None - for h in hosts: - node_db = lustreDB.lookup_name(h, 'node') - if node_db: - break - if not node_db: - print 'No host entry found.' - return - - router_flag = node_db.get_val_int('router', 0) - recovery_upcall = node_db.get_val('recovery_upcall', '') - timeout = node_db.get_val_int('timeout', 0) - - add_local_interfaces(node_db) - if not router_flag: - init_route_config(lustreDB) - - # Two step process: (1) load modules, (2) setup lustre - # if not cleaning, load modules first. - prof_list = node_db.get_refs('profile') - - if config.cleanup(): - if config.force(): - # the command line can override this value - timeout = 5 - # ugly hack, only need to run lctl commands for --dump - if config.lctl_dump(): - for_each_profile(node_db, prof_list, doCleanup) - return - - sys_set_timeout(timeout) - sys_set_recovery_upcall(recovery_upcall) - - for_each_profile(node_db, prof_list, doCleanup) - for_each_profile(node_db, prof_list, doUnloadModules) - - else: - # ugly hack, only need to run lctl commands for --dump - if config.lctl_dump(): - for_each_profile(node_db, prof_list, doSetup) - return - - for_each_profile(node_db, prof_list, doModules) - - sys_set_debug_path() - script = config.gdb_script() - run(lctl.lctl, ' modules >', script) - if config.gdb(): - log ("The GDB module script is in", script) - # pause, so user has time to break and - # load the script - time.sleep(5) - sys_set_timeout(timeout) - sys_set_recovery_upcall(recovery_upcall) - - for_each_profile(node_db, prof_list, doSetup) - -############################################################ -# 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=", - "timeout=", "recovery_upcall=", - "ldapurl=", "config=", "select=", "lctl_dump="] - 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) - if o == "--portals": - config.portals_dir(a) - if o == "--lustre": - config.lustre_dir(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 == "--minlevel": - config.minlevel(a) - if o == "--maxlevel": - config.maxlevel(a) - if o == "--timeout": - config.timeout(a) - if o == "--recovery_upcall": - config.recovery_upcall(a) - if o == "--ldapurl": - config.ldapurl(a) - if o == "--config": - config.config_name(a) - if o == "--select": - config.init_select(a) - if o == "--lctl_dump": - config.lctl_dump(a) - - return args - -def fetch(url): - import urllib - data = "" - try: - s = urllib.urlopen(url) - data = s.read() - except: - usage() - return data - -def setupModulePath(cmd, portals_dir = PORTALS_DIR): - base = os.path.dirname(cmd) - if os.access(base+"/Makefile", os.R_OK): - if not config.lustre_dir(): - config.lustre_dir(os.path.join(base, "..")) - # normalize the portals dir, using command line arg if set - if config.portals_dir(): - portals_dir = config.portals_dir() - dir = os.path.join(config.lustre_dir(), portals_dir) - config.portals_dir(dir) - elif config.lustre_dir() and config.portals_dir(): - # production mode - # if --lustre and --portals, normalize portals - # can ignore POTRALS_DIR here, since it is probly useless here - dir = config.portals_dir() - dir = os.path.join(config.lustre_dir(), dir) - config.portals_dir(dir) - -def sysctl(path, val): - if config.noexec(): - return - try: - fp = open(os.path.join('/proc/sys', path), 'w') - fp.write(str(val)) - fp.close() - except IOError, e: - print e - - -def sys_set_debug_path(): - debug("debug path: ", config.debug_path()) - sysctl('portals/debug_path', config.debug_path()) - -def sys_set_recovery_upcall(upcall): - # the command overrides the value in the node config - if config.recovery_upcall(): - upcall = config.recovery_upcall() - if upcall: - debug("setting recovery_upcall:", upcall) - sysctl('lustre/recovery_upcall', upcall) - -def sys_set_timeout(timeout): - # the command overrides the value in the node config - if config.timeout() > 0: - timeout = config.timeout() - if timeout > 0: - debug("setting timeout:", timeout) - sysctl('lustre/timeout', timeout) - -def sys_set_ptldebug(ptldebug): - # the command overrides the value in the node config - if config.ptldebug(): - ptldebug = config.ptldebug() - sysctl('portals/debug', ptldebug) - -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 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) - try: - dom = xml.dom.minidom.parse(args[0]) - except Exception: - panic("%s does not appear to be a config file." % (args[0])) - sys.exit(1) # make sure to die here, even in debug mode. - db = LustreDB_XML(dom.documentElement, dom.documentElement) - elif config.ldapurl(): - if not config.config_name(): - panic("--ldapurl requires --config name") - dn = "config=%s,fs=lustre" % (config.config_name()) - db = LustreDB_LDAP('', {}, base=dn, url = config.ldapurl()) - 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 - - setupModulePath(sys.argv[0]) - - lctl = LCTLInterface('lctl') - if config.lctl_dump(): - lctl.use_save_file(config.lctl_dump()) - else: - 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(db, 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 1efbd8c..0000000 --- a/lustre/utils/lctl.c +++ /dev/null @@ -1,257 +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 -#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"}, - {"dump", jt_ioc_dump, 0, "usage: dump file, save ioctl buffer to file"}, - - /* 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_obd_add_uuid, 0, "associate a UUID with a nid\n" - "usage: add_uuid "}, - {"close_uuid", jt_obd_close_uuid, 0, "disconnect a UUID\n" - "usage: close_uuid )"}, - {"del_uuid", jt_obd_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 [force]"}, - {"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]]]]"}, - {"get_stripe", jt_obd_get_stripe, 0, - "show stripe info for an echo client object\n" - "usage: get_stripe objid\n"}, - {"set_stripe", jt_obd_set_stripe, 0, - "set stripe info for an echo client object\n" - "usage: set_stripe objid[=width!count[@offset][:id:id...]\n"}, - {"unset_stripe", jt_obd_unset_stripe, 0, - "unset stripe info for an echo client object\n" - "usage: unset_stripe objid\n"}, - {"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 "}, - {"lookup", jt_obd_mdc_lookup, 0, "usage: lookup "}, - {"notransno", jt_obd_no_transno, 0, - "disable sending of committed-transno updates\n" - "usage: notransno"}, - {"readonly", jt_obd_set_readonly, 0, - "disable writes to the underlying device\n" - "usage: readonly"}, - - /* 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 aac0e16..0000000 --- a/lustre/utils/lfind.c +++ /dev/null @@ -1,331 +0,0 @@ -#define _XOPEN_SOURCE 500 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include -#include - -/* XXX 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, 'q'}, - {"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; -struct obd_uuid * obduuid; -__u32 obdcount; -__u32 obdindex; -char * buf; -int buflen; -struct obd_ioctl_data data; -struct lov_desc desc; -struct obd_uuid * 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 = (struct obd_uuid *)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; - - /* XXX 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 = (struct obd_uuid *)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 (getobdindex(path) == OBD_NOT_FOUND && obdcount == 0) { - /* terminate nftw walking this tree */ - return(1); - } - - if ((fd = open(path, O_RDONLY | O_LOV_DELAY_CREATE)) < 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"); - return 0; - } - - close(fd); - - if (query || verbose || - (obdindex != OBD_NOT_FOUND && - lmm->lmm_objects[obdindex].l_object_id)) - printf("%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: %u\n", (int)lmm->lmm_stripe_offset); - printf("lmm_stripe_count: %u\n", (int)lmm->lmm_stripe_count); - printf("lmm_stripe_size: %u\n", (int)lmm->lmm_stripe_size); - printf("lmm_ost_count: %u\n", lmm->lmm_ost_count); - printf("lmm_stripe_pattern: %d\n", lmm->lmm_magic & 0xf); - } - - count = lmm->lmm_ost_count; - - if (query || verbose) { - long long oid; - int ost = lmm->lmm_stripe_offset; - int header = 1; - - for (i = 0; i < count; i++, ost++) { - ost %= lmm->lmm_ost_count; - if ((oid = lmm->lmm_objects[ost].l_object_id)) { - if (header) { - printf("\tobdidx\t objid\n"); - header = 0; - } - printf("\t%6u\t%8llu%s\n", - ost, oid, obdindex == ost ? " *" : ""); - } - } - - if (query) - return(0); - } - - return(0); -} - -__u32 -getobdindex(const char *path) -{ - struct obd_uuid *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 || verbose) { - 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 56e58c8..0000000 --- a/lustre/utils/llanalyze +++ /dev/null @@ -1,278 +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 extracthostpid -{ - $line = shift; -# print "$_\n"; - 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($_); - $linehpid = extracthostpid($_); - $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 || $linehpid == $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/llparser.pm b/lustre/utils/llparser.pm deleted file mode 100644 index 5cee31f..0000000 --- a/lustre/utils/llparser.pm +++ /dev/null @@ -1,399 +0,0 @@ -#!/usr/bin/perl -# Copyright (C) 2002 Cluster File Systems, Inc. -# Author: Hariharan Thantry - -# This file is part of Lustre, http://www.lustre.org. -# -# Lustre is free software; you can redistribute it and/or -# modify it under the terms of version 2 of the GNU General Public -# License as published by the Free Software Foundation. -# -# Lustre is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Lustre; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - - -package llparser; -require Exporter; -@ISA = qw(Exporter); -@EXPORT = qw(parse_file print_rpcrelations parse_foptions %ll_subsystems - %subsysnum %trace_masks $e_subsys $e_mask $e_processor $e_time - $e_file $e_line $e_function $e_pid $e_stack $e_fmtstr $e_backref - $e_treeparent $e_numchildren $e_youngestchild $e_next $e_pidhead - $e_rpcsndrcv $e_rpcpid $e_rpcxid $e_rpcnid $e_rpcopc $e_rpcnext - $e_curlineref $SEND $RCV); - -($e_subsys, - $e_mask, - $e_processor, - $e_time, - $e_file, - $e_line, - $e_function, - $e_pid, - $e_stack, - $e_fmtstr, - $e_treeparent, - $e_numchildren, - $e_youngestchild, - $e_pidhead, - $e_next, - $e_backref) = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - -($e_rpcpid, - $e_rpcxid, - $e_rpcnid, - $e_rpcopc, - $e_rpcnext, - $e_rpcsndrcv, - $e_curlineref) = (0, 1, 2, 3, 4, 5, 6); - -$SEND = 0; -$RCV = 1; - -$REGEX=qr/^\s*(\w+)\s*:\s*(\d+)\s*:\s*(\d+)\s*:\s*(\d+\.(?:\d+))\s*\(\s*([^:]+)\s*:\s*(\d+)\s*:\s*([^()]+)\s*\(\)\s*(?:(?:\d+)\s*\|\s*)?(\d+)\s*\+\s*(\d+)\s*(?:.*)\):(.*)$/; - -$RPCREGEX = qr/^\s*(?:Sending|Handling)\s*RPC\s*pid:xid:nid:opc\s*(\d+):(?:0x)?(\w+):(?:0x)?(\w+):(\d+)\s*$/; -$FILEOPTIONREGEX = qr/(--server)|(-s)/; -$SENDING = qr/Sending/; - - -# Needs to match definition in portals/include/linux/kp30.h -%ll_subsystems = ("00" => "UNDEFINED", "01" => "MDC", "02" => "MDS", - "03" => "OSC", "04" => "OST", "05" => "CLASS", - "06" => "OBDFS","07" => "LLITE","08" => "RPC", - "09" => "EXT2OBD","0a" => "PORTALS","0b" => "SOCKNAL", - "0c" => "QSWNAL","0d" => "PINGER","0e" => "FILTER", - "0f" => "TRACE","10" => "ECHO","11" => "LDLM", - "12" => "LOV", "13" => "GMNAL","14" => "PTLROUTER" ); - -%subsysnum; -$subsysnum->{UNDEFINED} = 0; -$subsysnum->{MDC} = 1; -$subsysnum->{MDS} = 2; -$subsysnum->{OSC} = 3; -$subsysnum->{OST} = 4; -$subsysnum->{CLASS} = 5; -$subsysnum->{OBDFS} = 6; -$subsysnum->{LLITE} = 7; -$subsysnum->{RPC} = 8; -$subsysnum->{EXT2OBD} = 9; -$subsysnum->{PORTALS} = 10; -$subsysnum->{SOCKNAL} = 11; -$subsysnum->{QSWNAL} = 12; -$subsysnum->{PINGER} = 13; -$subsysnum->{FILTER} = 14; -$subsysnum->{TRACE} = 15; # obdtrace, not to be confused with D_TRACE */ -$subsysnum->{ECHO} = 16; -$subsysnum->{LDLM} = 17; -$subsysnum->{LOV} = 18; -$subsysnum->{GMNAL} = 19; -$subsysnum->{PTLROUTER} = 20; - -%tracemasks; -$tracemasks->{TRACE} = 1 << 0; # /* ENTRY/EXIT markers */ -$tracemasks->{INODE} = 1 << 1; # -$tracemasks->{SUPER} = 1 << 2; # -$tracemasks->{EXT2} = 1 << 3; # /* anything from ext2_debug */ -$tracemasks->{MALLOC} = 1 << 4; # /* print malloc, free information */ -$tracemasks->{CACHE} = 1 << 5; # /* cache-related items */ -$tracemasks->{INFO} = 1 << 6; # /* general information */ -$tracemasks->{IOCTL} = 1 << 7; # /* ioctl related information */ -$tracemasks->{BLOCKS} = 1 << 8; # /* ext2 block allocation */ -$tracemasks->{NET} = 1 << 9; # /* network communications */ -$tracemasks->{WARNING} = 1 << 10; # -$tracemasks->{BUFFS} = 1 << 11; # -$tracemasks->{OTHER} = 1 << 12; # -$tracemasks->{DENTRY} = 1 << 13; # -$tracemasks->{PORTALS} = 1 << 14; # /* ENTRY/EXIT markers */ -$tracemasks->{PAGE} = 1 << 15; # /* bulk page handling */ -$tracemasks->{DLMTRACE} = 1 << 16; # -$tracemasks->{ERROR} = 1 << 17; # /* CERROR} = ...) == CDEBUG} = D_ERROR, ...) */ -$tracemasks->{EMERG} = 1 << 18; # /* CEMERG} = ...) == CDEBUG} = D_EMERG, ...) */ -$tracemasks->{HA} = 1 << 19; # /* recovery and failover */ -$tracemasks->{RPCTRACE} = 1 << 19; # /* recovery and failover */ - -# Contains all the file names, the first filename is the -# client. After that are all servers. -my @filearray = (); - - -# Create backlinks between array entries based on the calling sequence -# For each new PID encountered, the first entry will be present in the -# PID hash. - -sub create_links { - my $arrayref = shift @_; - my $pidhashref = shift @_; - my $stitchref = shift @_; - my %local_hash; - my $hash_lineref; - my $tmpfmtref; - my $tmpref; - my $firstlineaftermarker = 0; - - foreach $lineref (@$arrayref) { - next if ($lineref->[$e_time] == 0); # Skip the client marker line - my $pidprevious = $pidhashref->{$lineref->[$e_pid]}; - if ($pidprevious->[$e_next] == 0) { - $pidprevious->[$e_next] = $lineref; - if (exists $local_hash{$lineref->[$e_pid]} - && $firstlineaftermarker) { - $hash_lineref=$local_hash{$lineref->[$e_pid]}; - $hash_lineref->[$e_next] =$lineref; - $firstlineaftermarker = 0; - } - } elsif ($local_hash{$lineref->[$e_pid]} == 0) { - # True only for the first line, the marker line. - $local_hash{$lineref->[$e_pid]}=$lineref; - #print "LINE ADDED TO HASH: @$lineref\n"; - $firstlineaftermarker = 1; - } - # Stack grows upward (assumes x86 kernel) - if ($lineref->[$e_stack] < $pidprevious->[$e_stack]) { - # lineref is not a child of pidprevious, find its parent - LINE: while(($lineref->[$e_stack] < $pidprevious->[$e_stack]) && - ($lineref->[$e_function] == $pidprevious->[$e_function]) - ) { - #This second part of the comparision is a HACK - last LINE if ($pidprevious->[$e_backref] == 0); - $pidprevious = $pidprevious->[$e_backref]; - } - } - if ($lineref->[$e_stack] > $pidprevious->[$e_stack]) { - # lineref is child of pidprevious, with the caveat that they must - # belong to different functions. This is a HACK - # until CDEBUG is modified - while($lineref->[$e_function] eq $pidprevious->[$e_function]) { - last if ($pidprevious->[$e_backref] == 0); - $pidprevious = $pidprevious->[$e_backref]; - } - - $lineref->[$e_backref] = $pidprevious; - $pidprevious->[$e_numchildren]++; - } else { - # lineref is sibling of pidprevious - $lineref->[$e_numchildren] = 0; - $lineref->[$e_backref] = $pidprevious->[$e_backref]; - ($lineref->[$e_backref])->[$e_numchildren]++; - } - - $pidhashref->{$lineref->[$e_pid]} = $lineref; - $lineref->[$e_youngestchild] = $lineref; - while ($pidprevious->[$e_backref] != 0) { - $pidprevious->[$e_youngestchild] = $lineref; - $pidprevious = $pidprevious->[$e_backref]; - } - $pidprevious->[$e_youngestchild] = $lineref; - $lineref->[$e_pidhead]=$pidprevious; - - # Stitch together rpc's - if($lineref->[$e_fmtstr] =~ $RPCREGEX) { - #print "RPC LINE: @$lineref\n"; - $tmpfmtref = [$1, $2, $3, $4, 0, 0, 0]; - if ($lineref->[$e_fmtstr] =~ $SENDING) { - $tmpfmtref->[$e_rpcsndrcv] = $SEND; - } else { $tmpfmtref->[$e_rpcsndrcv] = $RCV; } - $tmpfmtref->[$e_curlineref] = $lineref; - $stitchref->{$lineref->[$e_time]} = $tmpfmtref; - - } - - } -match_rpcs($stitchref); -return $arrayref; -} - - - - -# Main loop, parses the debug log - -sub parse_file { - my %hasharray; - my $input_files = shift; - - my $stitch_ref = shift; - my $pid = shift; - my $rpctrace = shift; - my $trace = shift; - my $nodlm = shift; - my $noclass = shift; - my $nonet = shift; - - print "$pid, $rpctrace, $nodlm, $noclass, $nonet\n"; - $backref = 0; - $treeparent = 0; - $numchildren = 0; - $youngestchild = 0; - $next = 0; - $pidhead = 0; - $iter = 0; - - foreach $file (@$input_files) { - - open(FILEHANDLE, $file) or die "Can't open file: $file\n"; - while() { - if (/$REGEX/) { - @parsed_line=($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, - $treeparent, $numchildren, $youngestchild, - $pidhead, $next, $backref); - next if (($parsed_line[$e_pid] != $pid) && - ($pid) && ($iter == 0)); - next if (($parsed_line[$e_mask] != $tracemasks->{RPCTRACE}) - && ($rpctrace)); - next if ($trace && $parsed_line[$e_mask] != - $tracemasks->{TRACE}); - next if ($nodlm && hex($parsed_line[$e_subsys]) == - $subsysnum->{LDLM}); - next if ($noclass && hex($parsed_line[$e_subsys]) == - $subsysnum->{CLASS}); - next if ($nonet && (hex($parsed_line[$e_subsys]) == - $subsysnum->{RPC} || - hex($parsed_line[$e_subsys]) == - $subsysnum->{NET} || - hex($parsed_line[$e_subsys]) == - $subsysnum->{PORTALS} || - hex($parsed_line[$e_subsys]) == - $subsysnum->{SOCKNAL} || - hex($parsed_line[$e_subsys]) == - $subsysnum->{QSWNAL} || - hex($parsed_line[$e_subsys]) == - $subsysnum->{GMNAL})); - - - if (!exists($hasharray{$parsed_line[$e_pid]})) { - # Push a marker for the beginning of this PID - my @marker_line; - $marker_line[$e_subsys] = 0; - $marker_line[$e_mask] = 0; - $marker_line[$e_processor] = 0; - $marker_line[$e_time] = $parsed_line[$e_time]; - $marker_line[$e_file] = 0; - $marker_line[$e_line] = 0; - $marker_line[$e_function] = 0; - $marker_line[$e_pid] = $parsed_line[$e_pid]; - # marker lines are everyone's parent, so stack value zero - $marker_line[$e_stack] = 0; - $marker_line[$e_fmtstr] = ""; - $marker_line[$e_treeparent] = 0; - $marker_line[$e_numchildren] = 0; - $marker_line[$e_youngestchild] = 0; - $marker_line[$e_pidhead] = 0; - $marker_line[$e_next]= \@parsed_line; - $marker_line[$e_backref] = 0; - $hasharray{$parsed_line[$e_pid]} = \@marker_line; - push @$array_parsed, [ @marker_line ]; - - } - push @$array_parsed, [ @parsed_line ]; - } - - } - close(FILEHANDLE); - if ($iter == 0) { - # Insert end of client line marker, an all zero pattern; - @marker_line = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - push @$array_parsed, [ @marker_line ]; - - } - $iter ++; - } - - $array_parsed=create_links($array_parsed, \%hasharray, $stitch_ref); - #print_array($array_parsed); - return $array_parsed; -} - -sub print_array { - - my $arrayref = shift; - foreach $lineref(@$arrayref){ - if ($lineref->[$e_backref]==0){ - print "MARKER LINE(addr): $lineref contents: [@$lineref]\n"; - } else { - - print "REGULAR LINE (addr) :$lineref contents:[@$lineref]\n"; - } - } - -} - -sub print_rpcrelations { - - my $rpchashref = shift; - foreach $rpckeys (sort keys %$rpchashref) { - $tmpref = $rpchashref->{$rpckeys}; - #print "Key: $rpckeys, Contents: @$tmpref\n"; - - } - -} -sub match_rpcs { - my $rpchashref = shift; - foreach $rpckeys (sort keys %$rpchashref) { - $tmpref = $rpchashref->{$rpckeys}; - #print "MATCHING: $@tmpref...\n"; - foreach $cmpkeys (sort keys %$rpchashref) { - next if($cmpkeys == $rpckeys); - $cmpref = $rpchashref->{$cmpkeys}; - # print "Line compared: @$cmpref\n"; - next if ($tmpref->[$e_rpcsndrcv] == $cmpref->[$e_rpcsndrcv]); - next if ($tmpref->[$e_rpcpid] != $cmpref->[$e_rpcpid]); - next if ($tmpref->[$e_rpcxid] != $cmpref->[$e_rpcxid]); - if ($tmpref->[$e_rpcsndrcv] == $SEND) { - $tmpref->[$e_rpcnext] = $cmpkeys; - #print "MACTHED: KEY 1: $rpckeys CONTENTS: @$tmpref", - #"KEY2: $cmpkeys CONTENTS: @$cmpref\n" - - } - - } - - } - -} - -sub getnextchild { - my $rootline = shift; - my $lineref = shift; - my $tempref = $lineref->[$e_next]; - if ($tempref == 0) { - return 0; - } - - if (($tempref->[$e_stack] > $rootline->[$e_stack]) || - (($tempref->[$e_stack] <= $rootline->[$e_stack]) && - ($tempref->[$e_function] == $rootline->[$e_function]) - )){ - # Child - return $tempref; - - } - return 0; - - -} - - -sub parse_foptions { - - my $inarg = shift; - my $idx = 0; - foreach $elem(@$inarg) { - next if ($elem =~ /$FILEOPTIONREGEX/); - $filearray[$idx] = $elem; - $idx++; - } - return \@filearray; -} - -1; -#$array_parsed=parse_file(); -#print_array($array_parsed); diff --git a/lustre/utils/lmc b/lustre/utils/lmc deleted file mode 100755 index 76757a7..0000000 --- a/lustre/utils/lmc +++ /dev/null @@ -1,955 +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 - - See lustre book for documentation for lmc. - -""" - -import sys, os, getopt, string, exceptions -import xml.dom.minidom -from xml.dom.ext import PrettyPrint - -DEFAULT_PORT = 988 - -def usage(): - print """usage: lmc --add object [object parameters] - -Object creation command summary: - ---add node - --node node_name - --timeout num - --recovery_upcall path - ---add net - --node node_name - --nid nid - --nettype tcp|elan|toe|gm - --hostaddr addr - --port port - --tcpbuf size - --irq_affinity 0|1 - --nid_exchange 0|1 - --router - ---add mds - --node node_name - --mds mds_name - --dev path - --fstype extN|ext3 - --size size - ---add lov - --lov lov_name - --mds mds_name - --stripe_sz num - --stripe_cnt num - --stripe_pattern num - --add ost - --node node_name - --ost ost_name - --lov lov_name - --dev path - --size size - --fstype extN|ext3 - --ostuuid uuid - ---add mtpt - Mountpoint - --node node_name - --path /mnt/point - --mds mds_name - --ost ost_name OR --lov lov_name -""" - sys.exit(1) - -def error(*args): - msg = string.join(map(str,args)) - raise OptionError("Error: " + msg) - -def panic(cmd, msg): - print "! " + cmd - print 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' - -ptlrpc_name = 'RPCDEV' -ptlrpc_uuid = 'RPCDEV_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, - ptlrpc_name, ptlrpc_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("uuid", uuid); - new.setAttribute("name", name); - 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, nid, net, hostaddr="", port=0, tcpbuf=0, irq_aff=0, nid_xchg=0): - """create node""" - network = self.newService("network", name, uuid) - network.setAttribute("nettype", net); - self.addElement(network, "nid", nid) - if hostaddr: - self.addElement(network, "hostaddr", hostaddr) - if port: - self.addElement(network, "port", "%d" %(port)) - if tcpbuf: - self.addElement(network, "sendmem", "%d" %(tcpbuf)) - self.addElement(network, "recvmem", "%d" %(tcpbuf)) - if irq_aff: - self.addElement(network, "irqaffinity", "%d" %(irq_aff)) - if nid_xchg: - self.addElement(network, "nidexchange", "%d" %(nid_xchg)) - - return network - - def routetbl(self, name, uuid): - """create node""" - rtbl = self.newService("routetbl", name, uuid) - return rtbl - - 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 profile(self, name, uuid): - """ create a host """ - profile = self.newService("profile", name, uuid) - return profile - - def node(self, name, uuid, prof_uuid): - """ create a host """ - node = self.newService("node", name, uuid) - node.appendChild(self.ref("profile", prof_uuid)) - return node - - def ldlm(self, name, uuid): - """ create a ldlm """ - ldlm = self.newService("ldlm", name, uuid) - return ldlm - - def osd(self, name, uuid, fs, osdtype, devname, format, ost_uuid, node_uuid, dev_size=0): - osd = self.newService("osd", name, uuid) - osd.setAttribute('osdtype', osdtype) - osd.appendChild(self.ref("target", ost_uuid)) - osd.appendChild(self.ref("node", node_uuid)) - if fs: - self.addElement(osd, "fstype", fs) - if devname: - dev = self.addElement(osd, "devpath", devname) - self.addElement(osd, "autoformat", format) - if dev_size: - self.addElement(osd, "devsize", "%s" % (dev_size)) - return osd - - def cobd(self, name, uuid, real_uuid, cache_uuid): - cobd = self.newService("cobd", name, uuid) - cobd.appendChild(self.ref("realobd",real_uuid)) - cobd.appendChild(self.ref("cacheobd",cache_uuid)) - return cobd - - def ost(self, name, uuid, osd_uuid): - ost = self.newService("ost", name, uuid) - ost.appendChild(self.ref("active", osd_uuid)) - return ost - - def oss(self, name, uuid): - oss = self.newService("oss", name, uuid) - return oss - - def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern): - lov = self.newService("lov", name, uuid) - lov.appendChild(self.ref("mds", mds_uuid)) - lov.setAttribute("stripesize", str(stripe_sz)) - lov.setAttribute("stripecount", str(stripe_cnt)) - lov.setAttribute("stripepattern", str(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, mdd_uuid): - mds = self.newService("mds", name, uuid) - mds.appendChild(self.ref("active",mdd_uuid)) - return mds - - def mdsdev(self, name, uuid, fs, devname, format, node_uuid, - mds_uuid, dev_size=0 ): - mdd = self.newService("mdsdev", name, uuid) - self.addElement(mdd, "fstype", fs) - dev = self.addElement(mdd, "devpath", devname) - self.addElement(mdd, "autoformat", format) - if dev_size: - self.addElement(mdd, "devsize", "%s" % (dev_size)) - mdd.appendChild(self.ref("node", node_uuid)) - mdd.appendChild(self.ref("target", mds_uuid)) - return mdd - - 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("obd", osc_uuid)) - self.addElement(mtpt, "path", path) - return mtpt - - def echo_client(self, name, uuid, osc_uuid): - ec = self.newService("echoclient", name, uuid) - ec.appendChild(self.ref("obd", 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 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_obd(gen, lov, osc_uuid): - lov.appendChild(gen.ref("obd", osc_uuid)) - -def ref_exists(profile, uuid): - elist = profile.childNodes - for e in elist: - if e.nodeType == e.ELEMENT_NODE: - ref = e.getAttribute('uuidref') - if ref == uuid: - return 1 - return 0 - -# ensure that uuid is not already in the profile -# return true if uuid is added -def node_add_profile(gen, node, ref, uuid): - refname = "%s_ref" % "profile" - ret = node.getElementsByTagName(refname) - if not ret: - error('node has no profile ref:', node) - prof_uuid = ret[0].getAttribute('uuidref') - profile = lookup(node.parentNode, prof_uuid) - if not profile: - error("no profile found:", prof_uuid) - if ref_exists(profile, uuid): - return 0 - profile.appendChild(gen.ref(ref, uuid)) - return 1 - -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) - prof_name = new_name("PROFILE_" + node_name) - prof_uuid = new_uuid(prof_name) - profile = gen.profile(prof_name, prof_uuid) - node = gen.node(node_name, uuid, prof_uuid) - lustre.appendChild(node) - lustre.appendChild(profile) - - node_add_profile(gen, node, 'ldlm', ldlm_uuid) - node_add_profile(gen, node, 'ptlrpc', ptlrpc_uuid) - if has_option(options, 'router'): - node.setAttribute('router', '1') - if has_option(options, 'timeout'): - node.setAttribute('timeout', get_option(options, 'timeout')) - if has_option(options, 'recovery_upcall'): - node.setAttribute('recovery_upcall', get_option(options, 'recovery_upcall')) - return node - - -def add_node(gen, lustre, options): - """ create a node with a network config """ - - node_name = get_option(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): - """ create a node with a network config """ - - node_name = get_option(options, 'node') - nid = get_option(options, 'nid') - hostaddr = get_option(options, 'hostaddr', '') - net_type = get_option(options, 'nettype') - - if net_type in ('tcp', 'toe'): - port = get_option_int(options, 'port', DEFAULT_PORT) - tcpbuf = get_option_int(options, 'tcpbuf', 0) - irq_aff = get_option_int(options, 'irq_affinity', 0) - nid_xchg = get_option_int(options, 'nid_exchange', 0) - elif net_type in ('elan', 'gm'): - port = 0 - tcpbuf = 0 - irq_aff = 0 - nid_xchg = 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, hostaddr, port, tcpbuf, irq_aff, nid_xchg)) - node_add_profile(gen, node, "network", net_uuid) - - -def add_route(gen, lustre, options): - """ create a node with a network config """ - - node_name = get_option(options, 'node') - net_type = get_option(options, 'nettype') - gw = get_option(options, 'gw') - lo = get_option(options, 'lo') - hi = get_option(options, 'hi', '') - - node = findByName(lustre, node_name, "node") - if not node: - error (node_name, " not found.") - - rlist = node.getElementsByTagName('routetbl') - if len(rlist) > 0: - rtbl = rlist[0] - else: - rtbl_name = new_name("RTBL_" + node_name) - rtbl_uuid = new_uuid(rtbl_name) - rtbl = gen.routetbl(rtbl_name, rtbl_uuid) - node.appendChild(rtbl) - node_add_profile(gen, node, "routetbl", rtbl_uuid) - rtbl.appendChild(gen.route(net_type, gw, lo, hi)) - - -def add_mds(gen, lustre, options): - node_name = get_option(options, 'node') - mds_name = get_option(options, 'mds') - mdd_name = new_name("MDD_" + mds_name +"_" + node_name) - mdd_uuid = new_uuid(mdd_name) - - mds_uuid = name2uuid(lustre, mds_name, fatal=0) - if not mds_uuid: - mds_uuid = new_uuid(mds_name) - mds = gen.mds(mds_name, mds_uuid, mdd_uuid) - lustre.appendChild(mds) - - devname = get_option(options, 'dev') - size = get_option(options, 'size', 0) - fstype = get_option(options, 'fstype', 'extN') - - node_uuid = name2uuid(lustre, node_name, 'node') - - node = findByName(lustre, node_name, "node") - node_add_profile(gen, node, "mdsdev", mdd_uuid) - net_uuid = get_net_uuid(lustre, node_name) - if not net_uuid: - error("NODE: ", node_name, "not found") - - mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname, get_format_flag(options), - node_uuid, mds_uuid, dev_size=size) - lustre.appendChild(mdd) - - -def add_ost(gen, lustre, options): - node_name = get_option(options, 'node') - lovname = get_option(options, 'lov', '') - osdtype = get_option(options, 'osdtype', 'obdfilter', deprecated_tag="obdtype") - - node_uuid = name2uuid(lustre, node_name) - - if osdtype == 'obdecho': - fstype = '' - devname = '' - size = 0 - fstype = '' - else: - devname = get_option(options, 'dev', '') # can be unset for bluearcs - size = get_option(options, 'size', 0) - fstype = get_option(options, 'fstype', 'extN') - - ostname = get_option(options, 'ost', '', deprecated_tag='obd') - if not ostname: - ostname = new_name('OST_'+ node_name) - - osdname = new_name("OSD_" + ostname) - osd_uuid = new_uuid(osdname) - - ost_uuid = name2uuid(lustre, ostname, fatal=0) - if not ost_uuid: - ost_uuid = get_option(options, 'ostuuid', '', deprecated_tag = 'obduuid') - if ost_uuid: - if lookup(lustre, ost_uuid): - error("Duplicate OST UUID:", ost_uuid) - else: - ost_uuid = new_uuid(ostname) - - ost = gen.ost(ostname, ost_uuid, osd_uuid) - lustre.appendChild(ost) - if lovname: - lov = findByName(lustre, lovname, "lov") - if not lov: - error('add_ost:', '"'+lovname+'"', "lov element not found.") - lov_add_obd(gen, lov, ost_uuid) - - osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname, get_format_flag(options), ost_uuid, - node_uuid, size) - - node = findByName(lustre, node_name, "node") - -## if node_add_profile(gen, node, 'oss', oss_uuid): -## ossname = 'OSS' -## oss_uuid = new_uuid(ossname) -## oss = gen.oss(ossname, oss_uuid) -## lustre.appendChild(oss) - - node_add_profile(gen, node, 'osd', osd_uuid) - lustre.appendChild(osd) - - -def add_cobd(gen, lustre, options): - node_name = get_option(options, 'node') - name = new_name('COBD_' + node_name) - uuid = new_uuid(name) - - real_name = get_option(options, 'real_obd') - cache_name = get_option(options, 'cache_obd') - - real_uuid = name2uuid(lustre, real_name, tag='obd') - cache_uuid = name2uuid(lustre, cache_name, tag='obd') - - node = findByName(lustre, node_name, "node") - node_add_profile(gen, node, "cobd", uuid) - cobd = gen.cobd(name, uuid, real_uuid, cache_uuid) - lustre.appendChild(cobd) - - -def add_echo_client(gen, lustre, options): - """ add an echo client to the profile for this node. """ - node_name = get_option(options, 'node') - lov_name = get_option(options, 'ost') - - node = findByName(lustre, node_name, 'node') - - echoname = new_name('ECHO_'+ node_name) - echo_uuid = new_uuid(echoname) - node_add_profile(gen, node, 'echoclient', echo_uuid) - - lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0) - if not lov_uuid: - lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1) - - echo = gen.echo_client(echoname, echo_uuid, lov_uuid) - lustre.appendChild(echo) - - -def add_lov(gen, lustre, options): - """ create a lov """ - - lov_orig = get_option(options, 'lov') - name = new_name(lov_orig) - if name != lov_orig: - warning("name:", lov_orig, "already used. using:", name) - - mds_name = get_option(options, 'mds') - stripe_sz = get_option_int(options, 'stripe_sz') - stripe_cnt = get_option_int(options, 'stripe_cnt', 0) - pattern = get_option_int(options, 'stripe_pattern', 0) - 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_cnt, pattern) - lustre.appendChild(lov) - - # add an lovconfig entry to the active mdsdev profile - lovconfig_name = new_name('LVCFG_' + name) - lovconfig_uuid = new_uuid(lovconfig_name) - mds = findByName(lustre, mds_name) - mds.appendChild(gen.ref("lovconfig", lovconfig_uuid)) - lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid) - lustre.appendChild(lovconfig) - - -def add_mtpt(gen, lustre, options): - """ create mtpt on a node """ - node_name = get_option(options, 'node') - - path = get_option(options, 'path') - mds_name = get_option(options, 'mds') - lov_name = get_option(options, 'lov', '') - if lov_name == '': - lov_name = get_option(options, 'ost', '', deprecated_tag='obd') - if lov_name == '': - error("--add mtpt requires either --lov lov_name or --ost ost_name") - - 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='ost', 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) - -# obsolete, leaving behind for reference -def add_oscref(gen, lustre, options): - """ create mtpt on a node """ - node_name = get_option(options, 'node') - osc_name = get_option(options, 'osc') - - osc_uuid = name2uuid(lustre, osc_name, tag='osc') - node = findByName(lustre, node_name, "node") - if not node: - error('node:', node_name, "not found") - node_add_profile(gen, node, "osc",osc_uuid) - -############################################################ -# Command line processing -# -class OptionError (exceptions.Exception): - def __init__(self, args): - self.args = args - -def has_option(options, tag): - """Look for tag in options hash and return the true if set""" - if options.has_key(tag): - return 1 - return 0 - -def get_option(options, tag, default = None, deprecated_tag=None): - """Look for tag in options hash and return the value if set. If not - set, then if return default it is set, otherwise exception.""" - if options.has_key(tag): - return options[tag] - elif deprecated_tag and options.has_key(deprecated_tag): - warning('--'+deprecated_tag, " is deprecated, please use:", '--'+tag) - return options[deprecated_tag] - elif default != None: - return default - else: - raise OptionError("--add %s requires --%s " % (options['add'], tag)) - # this exception should print an error like '--add blah requires -- value' - -def get_option_int(options, tag, default = None): - """Return an integer option. Raise exception if the value is not an int""" - val = get_option(options, tag, default) - try: - n = int(val) - except ValueError: - raise OptionError("--%s (value must be integer)" % (tag)) - return n - -def parse_cmdline(argv): - short_opts = "ho:i:m:" - long_opts = ["add=", "node=", "nettype=", "nid=", "tcpbuf=", "port=", - "echo_client=", "stripe_sz=", "stripe_cnt=", "stripe_pattern=", - "mds=", "route", "router", "merge=", "format", "reformat", "output=", - "dev=", "size=", "obd=", "ost=", "obdtype=", "osdtype=", "obduuid=", "in=", - "ostuuid=", "path=", "help", "batch=", "lov=", "gw=", "lo=", "hi=", - "osc=", "real_obd=", "cache_obd=", "fstype=", - "timeout=", "recovery_upcall=", "nid_exchange=", "irq_affinity=", - "hostaddr=",] - opts = [] - args = [] - options = {} - try: - opts, args = getopt.getopt(argv, short_opts, long_opts) - except getopt.error, e: - panic(string.join(sys.argv), e) - - for o, a in opts: - # Commands to create new devices - if o == "--add": - options['add'] = a - - if o == "--node": - options['node'] = a - - # devices names - if o == "--lov": - options['lov'] = a - if o == "--mds": - options['mds'] = a - if o == "--obd": - options['obd'] = a - if o == "--ost": - options['ost'] = a - - # node options - if o == "--timeout": - options['timeout'] = a - if o == "--recovery_upcall": - options['recovery_upcall'] = a - if o == "--router": - options['router'] = 1 - - # network options - if o == "--nid": - options['nid'] = a - if o == "--hostaddr": - options['hostaddr'] = a - if o == "--nettype": - options['nettype'] = a - if o == "--net": - options[''] = a - if o == "--tcpbuf": - options['tcpbuf'] = a - if o == "--port": - options['port'] = a - if o == "--mtpt": - options['mtpt'] = 1 - if o == "--route": - options['route'] = 1 - if o == "--nid_exchange": - options['nid_exchange'] = a - if o == "--irq_affinity": - options['irq_affinity'] = a - - # ost options - if o == "--dev": - options['dev'] = a - if o == "--size": - options['size'] = a - if o == "--path": - options['path'] = a - if o == "--osc": - options['osc'] = a - if o == "--obdtype": - options['obdtype'] = a - if o == "--osdtype": - options['osdtype'] = a - if o == "--fstype": - options['fstype'] = a - if o == "--obduuid": - options['obduuid'] = a - if o == "--ostuuid": - options['ostuuid'] = a - - # lov options - if o == "--stripe_sz": - options['stripe_sz'] = a - if o == "--stripe_cnt": - options['stripe_cnt'] = a - if o == "--stripe_pattern": - options['stripe_pattern'] = a - if o == "--gw": - options['gw'] = a - if o == "--lo": - options['lo'] = a - if o == "--hi": - options['hi'] = a - - # cobd - if o == "--cache_obd": - options['cache_obd'] = a - if o == "--real_obd": - options['real_obd'] = 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": - warning("the lmc --reformat option is not supported. Use lconf --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 add(devtype, gen, lustre, options): - if devtype == 'net': - add_net(gen, lustre, options) - elif devtype =='osc': - add_osc(gen, lustre, options) - elif devtype == 'mtpt': - add_mtpt(gen, lustre, options) - elif devtype == 'mds': - add_mds(gen, lustre, options) - elif devtype == 'ost': - add_ost(gen, lustre, options) - elif devtype == 'lov': - add_lov(gen, lustre, options) - elif devtype == 'route': - add_route(gen, lustre, options) - elif devtype == 'node': - add_node(gen, lustre, options) - elif devtype == 'echo_client': - add_echo_client(gen, lustre, options) - elif devtype == 'cobd': - add_cobd(gen, lustre, options) - else: - error("unknown device type:", devtype) - -def do_command(gen, lustre, options, args): - if options.has_key('add'): - add(options['add'], gen, lustre, options) - else: - error("Missing command") - -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)) - try: - do_command(gen, lustre, options, args) - except OptionError, e: - panic(cmd, e) - else: - try: - do_command(gen, lustre, options, args) - except OptionError, e: - panic(string.join(sys.argv),e) - - 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 39e2bdf..0000000 --- a/lustre/utils/lstripe.c +++ /dev/null @@ -1,111 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - - -/****************** Custom includes ********************/ -#include -#include - - -/****************** Functions ******************/ - -void usage(char *prog) -{ - fprintf(stderr, "usage: %s " - "\n", prog); - - fprintf(stderr, - "\tstripe size: number of bytes in each stripe (0 default)\n"); - fprintf(stderr, - "\tstripe start: OST index of first stripe (-1 default)\n"); - fprintf(stderr, - "\tstripe count: number of OSTs to stripe over (0 default)\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_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; - char *end; - - /* Check to make sure we have enough parameters */ - if (argc != 5) { - usage(argv[0]); - return 1; - } - - /* Get the stripe size */ - st_size = strtoul(argv[2], &end, 0); - if (*end != '\0') { - fprintf(stderr, "bad stripe size '%s'\n", argv[2]); - usage(argv[0]); - return 2; - } - - /* - if (st_size & 4095) { - fprintf(stderr, "stripe size must be multiple of page size\n"); - usage(argv[0]); - return 3; - } - */ - - /* Get the stripe offset*/ - st_offset = strtoul(argv[3], &end, 0); - if (*end != '\0') { - fprintf(stderr, "bad stripe offset '%s'\n", argv[3]); - usage(argv[0]); - return 4; - } - - /* Get the stripe count */ - st_count = strtoul(argv[4], &end, 0); - if (*end != '\0') { - fprintf(stderr, "bad stripe count '%s'\n", argv[4]); - usage(argv[0]); - return 5; - } - - /* 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/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 - -#ifndef __KERNEL__ -#include -#endif -#include -#include -#include -#include /* for struct lov_stripe_md */ -#include /* for IOC_LOV_SET_OSC_ACTIVE */ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include /* needed for PAGE_SIZE - rread */ - -#define __KERNEL__ -#include -#undef __KERNEL__ - -#include "obdctl.h" -#include -#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 - -uint64_t conn_addr = -1; -uint64_t conn_cookie; -char rawbuf[8192]; -char *buf = rawbuf; -int max = sizeof(rawbuf); - -static int thread; - -union lsm_buffer { - char space [4096]; - struct lov_stripe_md lsm; -} lsm_buffer; - -static char *cmdname(char *func); - -#define IOC_INIT(data) \ -do { \ - memset(&data, 0, sizeof(data)); \ - data.ioc_addr = conn_addr; \ - data.ioc_cookie = conn_cookie; \ -} while (0) - -#define IOC_PACK(func, data) \ -do { \ - memset(buf, 0, sizeof(rawbuf)); \ - 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; - - IOC_INIT(data); - - data.ioc_inllen1 = strlen(name) + 1; - data.ioc_inlbuf1 = name; - - IOC_PACK(func, data); - rc = l_ioctl(OBD_DEV_ID, 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 * -lsm_string (struct lov_stripe_md *lsm) -{ - static char buffer[4096]; - char *p = buffer; - int space = sizeof (buffer); - int i; - int nob; - - *p = 0; - space--; - - nob = snprintf(p, space, LPX64, lsm->lsm_object_id); - p += nob; - space -= nob; - - if (lsm->lsm_stripe_count != 0) { - nob = snprintf (p, space, "=%u#%u@%d", - lsm->lsm_stripe_size, - lsm->lsm_stripe_count, - lsm->lsm_stripe_offset); - p += nob; - space -= nob; - - for (i = 0; i < lsm->lsm_stripe_count; i++) { - nob = snprintf (p, space, ":"LPX64, - lsm->lsm_oinfo[i].loi_id); - p += nob; - space -= nob; - } - } - - if (space == 0) { /* probable overflow */ - fprintf (stderr, "lsm_string() overflowed buffer\n"); - abort (); - } - - return (buffer); -} - -static void -reset_lsmb (union lsm_buffer *lsmb) -{ - memset (lsmb->space, 0, sizeof (lsmb->space)); - lsmb->lsm.lsm_magic = LOV_MAGIC; -} - -static int -parse_lsm (union lsm_buffer *lsmb, char *string) -{ - struct lov_stripe_md *lsm = &lsmb->lsm; - char *end; - int i; - - /* - * object_id[=size#count[@offset][:id]*] - */ - - reset_lsmb (lsmb); - - lsm->lsm_object_id = strtoull (string, &end, 0); - if (end == string) - return (-1); - string = end; - - if (*string == 0) - return (0); - - if (*string != '=') - return (-1); - string++; - - lsm->lsm_stripe_size = strtoul (string, &end, 0); - if (end == string) - return (-1); - string = end; - - if (*string != '#') - return (-1); - string++; - - lsm->lsm_stripe_count = strtoul (string, &end, 0); - if (end == string) - return (-1); - string = end; - - if (*string == '@') { - string++; - lsm->lsm_stripe_offset = strtol (string, &end, 0); - if (end == string) - return (-1); - string = end; - } - - if (*string == 0) /* don't have to specify obj ids */ - return (0); - - for (i = 0; i < lsm->lsm_stripe_count; i++) { - if (*string != ':') - return (-1); - string++; - lsm->lsm_oinfo[i].loi_id = strtoull (string, &end, 0); - string = end; - } - - if (*string != 0) - return (-1); - - return (0); -} - -static char *cmdname(char *func) -{ - static char buf[512]; - - if (thread) { - sprintf(buf, "%s-%d", func, thread); - return buf; - } - - return func; -} - -#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; - - IOC_INIT(data); - - IOC_PACK(func, data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DISCONNECT, buf); - 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; - - IOC_PACK(func, data); - return l_ioctl(OBD_DEV_ID, 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; - - IOC_INIT(data); - - do_disconnect(argv[0], 1); - - /* XXX TODO: implement timeout per lctl usage for probe */ - if (argc != 1) - return CMD_HELP; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CONNECT, buf); - IOC_UNPACK(argv[0], 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; - int rc; - - IOC_INIT(data); - - if (argc != 1) - return CMD_HELP; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, 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; - char force = 'F'; - int rc; - - IOC_INIT(data); - - if (argc != 1 && argc != 2) - return CMD_HELP; - - if (argc == 2) { - if (strcmp(argv[1], "force")) - return CMD_HELP; - data.ioc_inllen1 = 1; - data.ioc_inlbuf1 = &force; - } - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CLEANUP, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - - return rc; -} - -int jt_obd_no_transno(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOC_INIT(data); - - if (argc != 1) - return CMD_HELP; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NO_TRANSNO, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - - return rc; -} - -int jt_obd_set_readonly(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOC_INIT(data); - - if (argc != 1) - return CMD_HELP; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_SET_READONLY, buf); - 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; - - IOC_INIT(data); - - if (argc != 1) - return CMD_HELP; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NEWDEV, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - else { - IOC_UNPACK(argv[0], data); - 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 (argc != 1) - return CMD_HELP; - - memset(buf, 0, sizeof(buf)); - data->ioc_version = OBD_IOCTL_VERSION; - data->ioc_addr = conn_addr; - data->ioc_cookie = conn_addr; - data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data)); - data->ioc_len = obd_ioctl_packlen(data); - - rc = l_ioctl(OBD_DEV_ID, OBD_GET_VERSION, buf); - 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 (argc != 1) - return CMD_HELP; - - memset(buf, 0, sizeof(buf)); - data->ioc_version = OBD_IOCTL_VERSION; - data->ioc_addr = conn_addr; - data->ioc_cookie = conn_addr; - data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data)); - data->ioc_len = obd_ioctl_packlen(data); - - rc = l_ioctl(OBD_DEV_ID, 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; - - IOC_INIT(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 = l_ioctl(OBD_DEV_ID, 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; - - IOC_INIT(data); - - if (argc > 4) - 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 > 2) { - data.ioc_inllen2 = strlen(argv[2]) + 1; - data.ioc_inlbuf2 = argv[2]; - } - if (argc > 3) { - data.ioc_inllen3 = strlen(argv[3]) + 1; - data.ioc_inlbuf3 = argv[3]; - } - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_SETUP, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - - return rc; -} - -/* Get echo client's stripe meta-data for the given object - */ -int jt_obd_get_stripe (int argc, char **argv) -{ - struct obd_ioctl_data data; - __u64 id; - int rc; - char *end; - - if (argc != 2) - return (CMD_HELP); - - id = strtoull (argv[1], &end, 0); - if (*end) { - fprintf (stderr, "Error: %s: invalid object id '%s'\n", - cmdname (argv[0]), argv[1]); - return (CMD_HELP); - } - - memset (&lsm_buffer, 0, sizeof (lsm_buffer)); - - IOC_INIT (data); - 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_pbuf1 = (char *)&lsm_buffer; - data.ioc_plen1 = sizeof (lsm_buffer); - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, ECHO_IOC_GET_STRIPE, buf); - IOC_UNPACK(argv[0], data); - - if (rc != 0) { - fprintf (stderr, "Error: %s: rc %d(%s)\n", - cmdname (argv[0]), rc, strerror (errno)); - return (rc); - } - - printf ("%s\n", lsm_string (&lsm_buffer.lsm)); - - return (rc); -} - -/* Set stripe meta-data for 1 or more objects. Object must be new to - * this echo client instance. - */ -int jt_obd_set_stripe (int argc, char **argv) -{ - struct obd_ioctl_data data; - char *end; - int count = 1; - int i; - int rc; - - if (argc < 2 || argc > 3) - return CMD_HELP; - - rc = parse_lsm (&lsm_buffer, argv[1]); - if (rc != 0) { - fprintf (stderr, "error: %s: invalid object '%s'\n", - cmdname (argv[0]), argv[1]); - return CMD_HELP; - } - - if (argc > 2) { - count = strtol (argv[2], &end, 0); - if (*end != 0) { - fprintf (stderr, "error: %s: invalid count '%s'\n", - cmdname (argv[0]), argv[1]); - return CMD_HELP; - } - } - - for (i = 0; i < count; i++) { - IOC_INIT (data); - data.ioc_obdo1.o_id = lsm_buffer.lsm.lsm_object_id + i; - data.ioc_obdo1.o_mode = S_IFREG | 0644; - data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE; - data.ioc_pbuf1 = (char *)&lsm_buffer; - data.ioc_plen1 = sizeof (lsm_buffer); - - IOC_PACK (argv[0], data); - rc = l_ioctl (OBD_DEV_ID, ECHO_IOC_SET_STRIPE, buf); - IOC_UNPACK (argv[0], data); - - if (rc != 0) { - fprintf (stderr, "Error: %s: rc %d(%s)\n", - cmdname (argv[0]), rc, strerror (errno)); - return (rc); - } - } - - return (0); -} - -/* Clear stripe meta-data info for an object on this echo-client instance - */ -int jt_obd_unset_stripe (int argc, char **argv) -{ - struct obd_ioctl_data data; - char *end; - obd_id id; - int rc; - - if (argc != 2) - return CMD_HELP; - - id = strtoll (argv[1], &end, 0); - if (*end == 0) { - fprintf (stderr, "error: %s: invalid object id '%s'\n", - cmdname (argv[0]), argv[1]); - return CMD_HELP; - } - - IOC_INIT (data); - data.ioc_obdo1.o_id = lsm_buffer.lsm.lsm_object_id; - data.ioc_obdo1.o_mode = S_IFREG | 0644; - data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE; - - IOC_PACK (argv[0], data); - rc = l_ioctl (OBD_DEV_ID, ECHO_IOC_SET_STRIPE, buf); - IOC_UNPACK (argv[0], data); - - if (rc != 0) - fprintf (stderr, "Error: %s: rc %d(%s)\n", - cmdname (argv[0]), rc, strerror (errno)); - - return (0); -} - -/* Create one or more objects, arg[1] may describe stripe meta-data. If - * not, defaults assumed. This echo-client instances stashes the stripe - * object ids. Use get_stripe on this node to print full lsm and - * set_stripe on another node to cut/paste between nodes. - */ -int jt_obd_create(int argc, char **argv) -{ - static __u64 base_id = 1; - - struct obd_ioctl_data data; - struct timeval next_time; - __u64 count = 1, next_count; - int verbose = 1, mode = 0100644, rc = 0, i; - char *end; - - IOC_INIT(data); - if (argc < 2 || argc > 5) - 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; - } - - if (argc < 5) - reset_lsmb (&lsm_buffer); /* will set default */ - else { - rc = parse_lsm (&lsm_buffer, argv[4]); - if (rc != 0) { - fprintf(stderr, "error: %s: invalid lsm '%s'\n", - cmdname(argv[0]), argv[4]); - return CMD_HELP; - } - base_id = lsm_buffer.lsm.lsm_object_id; - } - - 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 = base_id++; - 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_plen1 = sizeof (lsm_buffer); - data.ioc_pbuf1 = (char *)&lsm_buffer; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CREATE, buf); - IOC_UNPACK(argv[0], data); - 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; - } - - 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; - - IOC_INIT(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; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, 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; - - IOC_INIT(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; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, 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; - } - - 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; - - IOC_INIT(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); - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, 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; - - IOC_INIT(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; - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, 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; - - IOC_INIT(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; - - 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 = l_ioctl(OBD_DEV_ID, 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 = l_ioctl(OBD_DEV_ID, 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 = l_ioctl(OBD_DEV_ID, 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; - struct obd_uuid *uuidarray, *ptr; - int rc, i; - char *end; - - IOC_INIT(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 "LPSZ" chars\n", - cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1); - return -EINVAL; - } - - memset(&desc, 0, sizeof(desc)); - obd_str2uuid(&desc.ld_uuid, argv[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 = l_ioctl(OBD_DEV_ID, 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; - struct obd_uuid *uuidarray; - char *path; - int rc, fd; - - IOC_INIT(data); - - if (argc != 2) - return CMD_HELP; - - path = argv[1]; - fd = open(path, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "open \"%s\" failed: %s\n", path, - strerror(errno)); - return -1; - } - - memset(&desc, 0, sizeof(desc)); - obd_str2uuid(&desc.ld_uuid, argv[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); - rc = -ENOMEM; - goto out; - } - - 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 { - struct obd_uuid *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); - close(fd); - return rc; -} - -int jt_obd_test_ldlm(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOC_INIT(data); - if (argc != 1) - return CMD_HELP; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_TEST, buf); - 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; - - IOC_INIT(data); - if (argc != 1) - return CMD_HELP; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_DUMP, buf); - 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; - - IOC_INIT(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 = l_ioctl(OBD_DEV_ID, 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; - IOC_INIT(data); - - if (argc != 1) - return CMD_HELP; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_STOP, buf); - - 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; - - IOC_INIT(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 = l_ioctl(OBD_DEV_ID, 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; - - IOC_INIT(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 = l_ioctl(OBD_DEV_ID, 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; - - IOC_INIT(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 = l_ioctl(OBD_DEV_ID, OBD_IOC_RECOVD_FAILCONN, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - - return rc; -} - -int jt_obd_mdc_lookup(int argc, char **argv) -{ - struct obd_ioctl_data data; - char *parent, *child; - int rc, fd, verbose = 1; - - if (argc < 3 || argc > 4) - return CMD_HELP; - - parent = argv[1]; - child = argv[2]; - if (argc == 4) - verbose = get_verbose(argv[0], argv[3]); - - IOC_INIT(data); - - data.ioc_inllen1 = strlen(child) + 1; - data.ioc_inlbuf1 = child; - - IOC_PACK(argv[0], data); - - fd = open(parent, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "open \"%s\" failed: %s\n", parent, - strerror(errno)); - return -1; - } - - rc = ioctl(fd, IOC_MDC_LOOKUP, buf); - if (rc < 0) { - fprintf(stderr, "error: %s: ioctl error: %s\n", - cmdname(argv[0]), strerror(rc = errno)); - } - close(fd); - - if (verbose) { - IOC_UNPACK(argv[0], data); - printf("%s: mode %o uid %d gid %d\n", child, - data.ioc_obdo1.o_mode, data.ioc_obdo1.o_uid, - data.ioc_obdo1.o_gid); - } - - return rc; -} - -static -int do_add_uuid(char * func, char *uuid, ptl_nid_t nid, int nal) -{ - char tmp[64]; - int rc; - struct obd_ioctl_data data; - - IOC_INIT(data); - data.ioc_nid = nid; - data.ioc_inllen1 = strlen(uuid) + 1; - data.ioc_inlbuf1 = uuid; - data.ioc_nal = nal; - - IOC_PACK(func, data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_ADD_UUID, buf); - if (rc) { - fprintf(stderr, "IOC_PORTAL_ADD_UUID failed: %s\n", - strerror(errno)); - return -1; - } - - printf ("Added uuid %s: %s\n", uuid, ptl_nid2str (tmp, nid)); - return 0; -} - -int jt_obd_add_uuid(int argc, char **argv) -{ - ptl_nid_t nid = 0; - int nal; - - if (argc != 4) { - return CMD_HELP; - } - - if (ptl_parse_nid (&nid, argv[2]) != 0) { - fprintf (stderr, "Can't parse NID %s\n", argv[2]); - return (-1); - } - - nal = ptl_name2nal(argv[3]); - - if (nal == 0) { - fprintf (stderr, "Can't parse NAL %s\n", argv[3]); - return -1; - } - - return do_add_uuid(argv[0], argv[1], nid, nal); -} - -int jt_obd_close_uuid(int argc, char **argv) -{ - int rc, nal; - struct obd_ioctl_data data; - - if (argc != 3) { - fprintf(stderr, "usage: %s \n", argv[0]); - return 0; - } - - nal = ptl_name2nal(argv[2]); - - if (nal == 0) { - fprintf (stderr, "Can't parse NAL %s\n", argv[2]); - return -1; - } - - IOC_INIT(data); - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - data.ioc_nal = nal; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CLOSE_UUID, buf); - if (rc) { - fprintf(stderr, "IOC_PORTAL_CLOSE_UUID failed: %s\n", - strerror(errno)); - return -1; - } - return 0; -} - - -int jt_obd_del_uuid(int argc, char **argv) -{ - int rc; - struct obd_ioctl_data data; - - if (argc != 2) { - fprintf(stderr, "usage: %s \n", argv[0]); - return 0; - } - - IOC_INIT(data); - - if (strcmp (argv[1], "_all_")) - { - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - } - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DEL_UUID, buf); - if (rc) { - fprintf(stderr, "IOC_PORTAL_DEL_UUID failed: %s\n", - strerror(errno)); - return -1; - } - return 0; -} - -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(); - register_ioc_dev(OBD_DEV_ID, OBD_DEV_PATH); - - 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/obdbarrier.c b/lustre/utils/obdbarrier.c deleted file mode 100644 index 3363824..0000000 --- a/lustre/utils/obdbarrier.c +++ /dev/null @@ -1,224 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Eric Barton - * - * 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 "obdiolib.h" - -int -parse_kmg (uint64_t *valp, char *str) -{ - uint64_t val; - char mod[32]; - - switch (sscanf (str, LPU64"%1[gGmMkK]", &val, mod)) - { - default: - return (-1); - - case 1: - *valp = val; - return (0); - - case 2: - switch (*mod) - { - case 'g': - case 'G': - *valp = val << 30; - return (0); - - case 'm': - case 'M': - *valp = val << 20; - return (0); - - case 'k': - case 'K': - *valp = val << 10; - return (0); - - default: - *valp = val; - return (0); - } - } -} - -void -usage (char *cmdname, int help) -{ - char *name = strrchr (cmdname, '/'); - - if (name == NULL) - name = cmdname; - - fprintf (help ? stdout : stderr, - "usage: %s -d device -s size -o offset [-i id][-n reps][-l] oid\n", - name); -} - -int -exponential_modulus (int i, int base) -{ - int top = base; - int mod = 1; - - for (;;) { - if (i < top) - return (i%mod == 0); - - mod = top; - top *= base; - } -} - -int -main (int argc, char **argv) -{ - uint64_t bid = (((uint64_t)gethostid()) << 32) | getpid (); - int set_bid = 0; - uint64_t oid; - int setup = 0; - int device = -1; - int npeers = 0; - int reps = 1; - char hostname[128]; - struct obdio_conn *conn; - struct obdio_barrier *b; - char *end; - uint64_t val; - int rc; - int c; - - setvbuf (stdout, NULL, _IOLBF, 0); - memset (hostname, 0, sizeof (hostname)); - gethostname (hostname, sizeof (hostname)); - hostname[sizeof(hostname) - 1] = 0; - - while ((c = getopt (argc, argv, "hsi:d:n:p:")) != -1) - switch (c) { - case 'h': - usage (argv[0], 1); - return (0); - - case 'i': - bid = strtoll (optarg, &end, 0); - if (end == optarg || *end != 0) { - fprintf (stderr, "Can't parse id %s\n", - optarg); - return (1); - } - set_bid = 1; - break; - - case 's': - setup = 1; - break; - - case 'd': - device = strtol (optarg, &end, 0); - if (end == optarg || *end != 0 || device < 0) { - fprintf (stderr, "Can't parse device %s\n", - optarg); - return (1); - } - break; - - case 'n': - if (parse_kmg (&val, optarg) != 0) { - fprintf (stderr, "Can't parse reps %s\n", - optarg); - return (1); - } - reps = (int)val; - break; - - case 'p': - npeers = strtol (optarg, &end, 0); - if (end == optarg || *end != 0 || npeers <= 0) { - fprintf (stderr, "Can't parse npeers %s\n", - optarg); - return (1); - } - break; - - default: - usage (argv[0], 0); - return (1); - } - - if ((!setup && !set_bid) || - npeers <= 0 || - device < 0 || - optind == argc) { - fprintf (stderr, "%s not specified\n", - (!setup && !set_bid) ? "id" : - npeers <= 0 ? "npeers" : - device < 0 ? "device" : "object id"); - return (1); - } - - oid = strtoull (argv[optind], &end, 0); - if (end == argv[optind] || *end != 0) { - fprintf (stderr, "Can't parse object id %s\n", - argv[optind]); - return (1); - } - - conn = obdio_connect (device); - if (conn == NULL) - return (1); - - b = obdio_new_barrier (oid, bid, npeers); - if (b == NULL) - return (1); - - rc = 0; - if (setup) { - rc = obdio_setup_barrier (conn, b); - if (rc == 0) - printf ("Setup barrier: -d %d -i "LPX64" -p %d -n1 "LPX64"\n", - device, bid, npeers, oid); - } else { - for (c = 0; c < reps; c++) { - rc = obdio_barrier (conn, b); - if (rc != 0) - break; - if (exponential_modulus (c, 10)) - printf ("%s: Barrier %d\n", hostname, c); - } - } - - free (b); - - obdio_disconnect (conn); - - return (rc == 0 ? 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 f0e1a97..0000000 --- a/lustre/utils/obdctl.h +++ /dev/null @@ -1,72 +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_no_transno(int argc, char **argv); -int jt_obd_set_readonly(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_get_stripe(int argc, char **argv); -int jt_obd_set_stripe(int argc, char **argv); -int jt_obd_unset_stripe(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_obd_mdc_lookup(int argc, char **argv); -int jt_get_version(int argc, char **argv); -int jt_obd_add_uuid(int argc, char **argv); -int jt_obd_close_uuid(int argc, char **argv); -int jt_obd_del_uuid(int argc, char **argv); - -#endif diff --git a/lustre/utils/obdio.c b/lustre/utils/obdio.c deleted file mode 100644 index 65a4cac..0000000 --- a/lustre/utils/obdio.c +++ /dev/null @@ -1,305 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Eric Barton - * - * 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 "obdiolib.h" - -int -obdio_test_fixed_extent (struct obdio_conn *conn, - uint32_t myhid, uint32_t mypid, - int reps, int locked, uint64_t oid, - uint64_t offset, uint32_t size) -{ - struct lustre_handle fh; - struct lustre_handle lh; - void *space; - void *buffer; - uint32_t *ibuf; - int i; - int j; - int rc; - int rc2; - - rc = obdio_open (conn, oid, &fh); - if (rc != 0) { - fprintf (stderr, "Failed to open object "LPX64": %s\n", - oid, strerror (errno)); - return (rc); - } - - buffer = obdio_alloc_aligned_buffer (&space, size); - if (buffer == NULL) { - fprintf (stderr, "Can't allocate buffer size %d\n", size); - rc = -1; - goto out_0; - } - - for (i = 0; i < reps; i++) { - ibuf = (uint32_t *) buffer; - for (j = 0; j < size / (4 * sizeof (*ibuf)); j++) { - ibuf[0] = myhid; - ibuf[1] = mypid; - ibuf[2] = i; - ibuf[3] = j; - ibuf += 4; - } - - if (locked) { - rc = obdio_enqueue (conn, oid, LCK_PW, offset, size, &lh); - if (rc != 0) { - fprintf (stderr, "Error on enqueue "LPX64" @ "LPU64" for %u: %s\n", - oid, offset, size, strerror (errno)); - goto out_1; - } - } - - rc = obdio_pwrite (conn, oid, buffer, size, offset); - if (rc != 0) { - fprintf (stderr, "Error writing "LPX64" @ "LPU64" for %u: %s\n", - oid, offset, size, strerror (errno)); - if (locked) - obdio_cancel (conn, &lh); - rc = -1; - goto out_1; - } - - memset (buffer, 0xbb, size); - - rc = obdio_pread (conn, oid, buffer, size, offset); - if (rc != 0) { - fprintf (stderr, "Error reading "LPX64" @ "LPU64" for %u: %s\n", - oid, offset, size, strerror (errno)); - if (locked) - obdio_cancel (conn, &lh); - rc = -1; - goto out_1; - } - - if (locked) { - rc = obdio_cancel (conn, &lh); - if (rc != 0) { - fprintf (stderr, "Error on cancel "LPX64" @ "LPU64" for %u: %s\n", - oid, offset, size, strerror (errno)); - rc = -1; - goto out_1; - } - } - - ibuf = (uint32_t *) buffer; - for (j = 0; j < size / (4 * sizeof (*ibuf)); j++) { - if (ibuf[0] != myhid || - ibuf[1] != mypid || - ibuf[2] != i || - ibuf[3] != j) { - fprintf (stderr, "Error checking "LPX64" @ "LPU64" for %u, chunk %d\n", - oid, offset, size, j); - fprintf (stderr, "Expected [%x,%x,%x,%x], got [%x,%x,%x,%x]\n", - myhid, mypid, i, j, ibuf[0], ibuf[1], ibuf[2], ibuf[3]); - rc = -1; - goto out_1; - } - ibuf += 4; - } - } - out_1: - free (space); - out_0: - rc2 = obdio_close (conn, oid, &fh); - if (rc2 != 0) - fprintf (stderr, "Error closing object "LPX64": %s\n", - oid, strerror (errno)); - return (rc); -} - -int -parse_kmg (uint64_t *valp, char *str) -{ - uint64_t val; - char mod[32]; - - switch (sscanf (str, LPU64"%1[gGmMkK]", &val, mod)) - { - default: - return (-1); - - case 1: - *valp = val; - return (0); - - case 2: - switch (*mod) - { - case 'g': - case 'G': - *valp = val << 30; - return (0); - - case 'm': - case 'M': - *valp = val << 20; - return (0); - - case 'k': - case 'K': - *valp = val << 10; - return (0); - - default: - *valp = val; - return (0); - } - } -} - -void -usage (char *cmdname, int help) -{ - char *name = strrchr (cmdname, '/'); - - if (name == NULL) - name = cmdname; - - fprintf (help ? stdout : stderr, - "usage: %s -d device -s size -o offset [-i id][-n reps][-l] oid\n", - name); -} - -int -main (int argc, char **argv) -{ - uint32_t mypid = getpid (); - uint32_t myhid = gethostid (); - uint64_t oid; - uint64_t base_offset = 0; - uint32_t size = 0; - int set_size = 0; - int device = -1; - int reps = 1; - int locked = 0; - char *end; - struct obdio_conn *conn; - uint64_t val; - int v1; - int v2; - int rc; - int c; - - while ((c = getopt (argc, argv, "hi:s:o:d:n:l")) != -1) - switch (c) { - case 'h': - usage (argv[0], 1); - return (0); - - case 'i': - switch (sscanf (optarg, "%i.%i", &v1, &v2)) { - case 1: - mypid = v1; - break; - case 2: - myhid = v1; - mypid = v2; - break; - default: - fprintf (stderr, "Can't parse id %s\n", - optarg); - return (1); - } - break; - - case 's': - if (parse_kmg (&val, optarg) != 0) { - fprintf (stderr, "Can't parse size %s\n", - optarg); - return (1); - } - size = (uint32_t)val; - set_size++; - break; - - case 'o': - if (parse_kmg (&val, optarg) != 0) { - fprintf (stderr, "Can't parse offset %s\n", - optarg); - return (1); - } - base_offset = val; - break; - - case 'd': - device = strtol (optarg, &end, 0); - if (end == optarg || *end != 0 || device < 0) { - fprintf (stderr, "Can't parse device %s\n", - optarg); - return (1); - } - break; - case 'n': - if (parse_kmg (&val, optarg) != 0) { - fprintf (stderr, "Can't parse reps %s\n", - optarg); - return (1); - } - reps = (int)val; - break; - case 'l': - locked = 1; - break; - default: - usage (argv[0], 0); - return (1); - } - - if (!set_size || - device < 0 || - optind == argc) { - fprintf (stderr, "No %s specified\n", - !set_size ? "size" : - device < 0 ? "device" : "object id"); - return (1); - } - - oid = strtoull (argv[optind], &end, 0); - if (end == argv[optind] || *end != 0) { - fprintf (stderr, "Can't parse object id %s\n", - argv[optind]); - return (1); - } - - conn = obdio_connect (device); - if (conn == NULL) - return (1); - - rc = obdio_test_fixed_extent (conn, myhid, mypid, reps, locked, - oid, base_offset, size); - - obdio_disconnect (conn); - - return (rc == 0 ? 0 : 1); -} - - diff --git a/lustre/utils/obdiolib.c b/lustre/utils/obdiolib.c deleted file mode 100644 index 0404808..0000000 --- a/lustre/utils/obdiolib.c +++ /dev/null @@ -1,466 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2003 Cluster File Systems, Inc. - * Author: Eric Barton - * - * 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 "obdiolib.h" - -void -obdio_iocinit (struct obdio_conn *conn) -{ - memset (&conn->oc_data, 0, sizeof (conn->oc_data)); - conn->oc_data.ioc_version = OBD_IOCTL_VERSION; - conn->oc_data.ioc_addr = conn->oc_conn_addr; - conn->oc_data.ioc_cookie = conn->oc_conn_cookie; - conn->oc_data.ioc_len = sizeof (conn->oc_data); -} - -int -obdio_ioctl (struct obdio_conn *conn, int cmd) -{ - char *buf = conn->oc_buffer; - int rc; - int rc2; - - rc = obd_ioctl_pack (&conn->oc_data, &buf, sizeof (conn->oc_buffer)); - if (rc != 0) { - fprintf (stderr, "obdio_ioctl: obd_ioctl_pack: %d (%s)\n", - rc, strerror (errno)); - abort (); - } - - rc = ioctl (conn->oc_fd, cmd, buf); - if (rc != 0) - return (rc); - - rc2 = obd_ioctl_unpack (&conn->oc_data, buf, sizeof (conn->oc_buffer)); - if (rc2 != 0) { - fprintf (stderr, "obdio_ioctl: obd_ioctl_unpack: %d (%s)\n", - rc2, strerror (errno)); - abort (); - } - - return (rc); -} - -struct obdio_conn * -obdio_connect (int device) -{ - struct obdio_conn *conn; - int rc; - - conn = malloc (sizeof (*conn)); - if (conn == NULL) { - fprintf (stderr, "obdio_connect: no memory\n"); - return (NULL); - } - memset (conn, 0, sizeof (*conn)); - - conn->oc_fd = open ("/dev/obd", O_RDWR); - if (conn->oc_fd < 0) { - fprintf (stderr, "obdio_connect: Can't open /dev/obd: %s\n", - strerror (errno)); - goto failed; - } - - obdio_iocinit (conn); - conn->oc_data.ioc_dev = device; - rc = obdio_ioctl (conn, OBD_IOC_DEVICE); - if (rc != 0) { - fprintf (stderr, "obdio_connect: Can't set device %d: %s\n", - device, strerror (errno)); - goto failed; - } - - obdio_iocinit (conn); - rc = obdio_ioctl (conn, OBD_IOC_CONNECT); - if (rc != 0) { - fprintf (stderr, "obdio_connect: Can't connect to device %d: %s\n", - device, strerror (errno)); - goto failed; - } - - conn->oc_conn_addr = conn->oc_data.ioc_addr; - conn->oc_conn_cookie = conn->oc_data.ioc_cookie; - return (conn); - - failed: - free (conn); - return (NULL); -} - -void -obdio_disconnect (struct obdio_conn *conn) -{ - close (conn->oc_fd); - /* obdclass will automatically close on last ref */ - free (conn); -} - -int -obdio_open (struct obdio_conn *conn, uint64_t oid, struct lustre_handle *fh) -{ - int rc; - - obdio_iocinit (conn); - - conn->oc_data.ioc_obdo1.o_id = oid; - conn->oc_data.ioc_obdo1.o_mode = S_IFREG; - conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; - - rc = obdio_ioctl (conn, OBD_IOC_OPEN); - - if (rc == 0) - memcpy (fh, obdo_handle(&conn->oc_data.ioc_obdo1), sizeof (*fh)); - - return (rc); -} - -int -obdio_close (struct obdio_conn *conn, uint64_t oid, struct lustre_handle *fh) -{ - obdio_iocinit (conn); - - - conn->oc_data.ioc_obdo1.o_id = oid; - conn->oc_data.ioc_obdo1.o_mode = S_IFREG; - memcpy (obdo_handle (&conn->oc_data.ioc_obdo1), fh, sizeof (*fh)); - conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | - OBD_MD_FLMODE | OBD_MD_FLHANDLE; - - return (obdio_ioctl (conn, OBD_IOC_CLOSE)); -} - -int -obdio_pread (struct obdio_conn *conn, uint64_t oid, - char *buffer, uint32_t count, uint64_t offset) -{ - obdio_iocinit (conn); - - conn->oc_data.ioc_obdo1.o_id = oid; - conn->oc_data.ioc_obdo1.o_mode = S_IFREG; - conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; - - conn->oc_data.ioc_pbuf2 = buffer; - conn->oc_data.ioc_plen2 = count; - conn->oc_data.ioc_count = count; - conn->oc_data.ioc_offset = offset; - - return (obdio_ioctl (conn, OBD_IOC_BRW_READ)); -} - -int -obdio_pwrite (struct obdio_conn *conn, uint64_t oid, - char *buffer, uint32_t count, uint64_t offset) -{ - obdio_iocinit (conn); - - conn->oc_data.ioc_obdo1.o_id = oid; - conn->oc_data.ioc_obdo1.o_mode = S_IFREG; - conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; - - conn->oc_data.ioc_pbuf2 = buffer; - conn->oc_data.ioc_plen2 = count; - conn->oc_data.ioc_count = count; - conn->oc_data.ioc_offset = offset; - - return (obdio_ioctl (conn, OBD_IOC_BRW_WRITE)); -} - -int -obdio_enqueue (struct obdio_conn *conn, uint64_t oid, - int mode, uint64_t offset, uint32_t count, - struct lustre_handle *lh) -{ - int rc; - - obdio_iocinit (conn); - - conn->oc_data.ioc_obdo1.o_id = oid; - conn->oc_data.ioc_obdo1.o_mode = S_IFREG; - conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; - - conn->oc_data.ioc_conn1 = mode; - conn->oc_data.ioc_count = count; - conn->oc_data.ioc_offset = offset; - - rc = obdio_ioctl (conn, ECHO_IOC_ENQUEUE); - - if (rc == 0) - memcpy (lh, obdo_handle (&conn->oc_data.ioc_obdo1), sizeof (*lh)); - - return (rc); -} - -int -obdio_cancel (struct obdio_conn *conn, struct lustre_handle *lh) -{ - obdio_iocinit (conn); - - memcpy (obdo_handle (&conn->oc_data.ioc_obdo1), lh, sizeof (*lh)); - conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLHANDLE; - - return (obdio_ioctl (conn, ECHO_IOC_CANCEL)); -} - -void * -obdio_alloc_aligned_buffer (void **spacep, int size) -{ - int pagesize = getpagesize(); - void *space = malloc (size + pagesize - 1); - - *spacep = space; - if (space == NULL) - return (NULL); - - return ((void *)(((unsigned long)space + pagesize - 1) & ~(pagesize - 1))); -} - -struct obdio_barrier * -obdio_new_barrier (uint64_t oid, uint64_t id, int npeers) -{ - struct obdio_barrier *b; - - b = (struct obdio_barrier *)malloc (sizeof (*b)); - if (b == NULL) { - fprintf (stderr, "obdio_new_barrier "LPX64": Can't allocate\n", oid); - return (NULL); - } - - b->ob_id = id; - b->ob_oid = oid; - b->ob_npeers = npeers; - b->ob_ordinal = 0; - b->ob_count = 0; - return (b); -} - -int -obdio_setup_barrier (struct obdio_conn *conn, struct obdio_barrier *b) -{ - struct lustre_handle fh; - struct lustre_handle lh; - int rc; - int rc2; - void *space; - struct obdio_barrier *fileb; - - if (b->ob_ordinal != 0 || - b->ob_count != 0) { - fprintf (stderr, "obdio_setup_barrier: invalid parameter\n"); - abort (); - } - - rc = obdio_open (conn, b->ob_oid, &fh); - if (rc != 0) { - fprintf (stderr, "obdio_setup_barrier "LPX64": Failed to open object: %s\n", - b->ob_oid, strerror (errno)); - return (rc); - } - - fileb = (struct obdio_barrier *) obdio_alloc_aligned_buffer (&space, getpagesize ()); - if (fileb == NULL) { - fprintf (stderr, "obdio_setup_barrier "LPX64": Can't allocate page buffer\n", - b->ob_oid); - rc = -1; - goto out_0; - } - - memset (fileb, 0, getpagesize ()); - *fileb = *b; - - rc = obdio_enqueue (conn, b->ob_oid, LCK_PW, 0, getpagesize (), &lh); - if (rc != 0) { - fprintf (stderr, "obdio_setup_barrier "LPX64": Error on enqueue: %s\n", - b->ob_oid, strerror (errno)); - goto out_1; - } - - rc = obdio_pwrite (conn, b->ob_oid, (void *)fileb, getpagesize (), 0); - if (rc != 0) - fprintf (stderr, "obdio_setup_barrier "LPX64": Error on write: %s\n", - b->ob_oid, strerror (errno)); - - rc2 = obdio_cancel (conn, &lh); - if (rc == 0 && rc2 != 0) { - fprintf (stderr, "obdio_setup_barrier "LPX64": Error on cancel: %s\n", - b->ob_oid, strerror (errno)); - rc = rc2; - } - out_1: - free (space); - out_0: - rc2 = obdio_close (conn, b->ob_oid, &fh); - if (rc == 0 && rc2 != 0) { - fprintf (stderr, "obdio_setup_barrier "LPX64": Error on close: %s\n", - b->ob_oid, strerror (errno)); - rc = rc2; - } - - return (rc); -} - -int -obdio_barrier (struct obdio_conn *conn, struct obdio_barrier *b) -{ - struct lustre_handle fh; - struct lustre_handle lh; - int rc; - int rc2; - void *space; - struct obdio_barrier *fileb; - char *mode; - - rc = obdio_open (conn, b->ob_oid, &fh); - if (rc != 0) { - fprintf (stderr, "obdio_barrier "LPX64": Error on open: %s\n", - b->ob_oid, strerror (errno)); - return (rc); - } - - fileb = (struct obdio_barrier *) obdio_alloc_aligned_buffer (&space, getpagesize ()); - if (fileb == NULL) { - fprintf (stderr, "obdio_barrier "LPX64": Can't allocate page buffer\n", - b->ob_oid); - rc = -1; - goto out_0; - } - - rc = obdio_enqueue (conn, b->ob_oid, LCK_PW, 0, getpagesize (), &lh); - if (rc != 0) { - fprintf (stderr, "obdio_barrier "LPX64": Error on PW enqueue: %s\n", - b->ob_oid, strerror (errno)); - goto out_1; - } - - memset (fileb, 0xeb, getpagesize ()); - rc = obdio_pread (conn, b->ob_oid, (void *)fileb, getpagesize (), 0); - if (rc != 0) { - fprintf (stderr, "obdio_barrier "LPX64": Error on initial read: %s\n", - b->ob_oid, strerror (errno)); - goto out_2; - } - - if (fileb->ob_id != b->ob_id || - fileb->ob_oid != b->ob_oid || - fileb->ob_npeers != b->ob_npeers || - fileb->ob_count >= b->ob_npeers || - fileb->ob_ordinal != b->ob_ordinal) { - fprintf (stderr, "obdio_barrier "LPX64": corrupt on initial read\n", b->ob_id); - fprintf (stderr, " got ["LPX64","LPX64","LPX64","LPX64","LPX64"]\n", - fileb->ob_id, fileb->ob_oid, fileb->ob_npeers, - fileb->ob_ordinal, fileb->ob_count); - fprintf (stderr, " expected ["LPX64","LPX64","LPX64","LPX64","LPX64"]\n", - b->ob_id, b->ob_oid, b->ob_npeers, - b->ob_ordinal, b->ob_count); - rc = -1; - goto out_2; - } - - fileb->ob_count++; - if (fileb->ob_count == fileb->ob_npeers) { /* I'm the last joiner */ - fileb->ob_count = 0; /* join count for next barrier */ - fileb->ob_ordinal++; /* signal all joined */ - } - - rc = obdio_pwrite (conn, b->ob_oid, (void *)fileb, getpagesize (), 0); - if (rc != 0) { - fprintf (stderr, "obdio_barrier "LPX64": Error on initial write: %s\n", - b->ob_oid, strerror (errno)); - goto out_2; - } - - mode = "PW"; - b->ob_ordinal++; /* now I wait... */ - while (fileb->ob_ordinal != b->ob_ordinal) { - - rc = obdio_cancel (conn, &lh); - if (rc != 0) { - fprintf (stderr, "obdio_barrier "LPX64": Error on %s cancel: %s\n", - b->ob_oid, mode, strerror (errno)); - goto out_1; - } - - mode = "PR"; - rc = obdio_enqueue (conn, b->ob_oid, LCK_PR, 0, getpagesize (), &lh); - if (rc != 0) { - fprintf (stderr, "obdio_barrier "LPX64": Error on PR enqueue: %s\n", - b->ob_oid, strerror (errno)); - goto out_1; - } - - memset (fileb, 0xeb, getpagesize ()); - rc = obdio_pread (conn, b->ob_oid, (void *)fileb, getpagesize (), 0); - if (rc != 0) { - fprintf (stderr, "obdio_barrier "LPX64": Error on read: %s\n", - b->ob_oid, strerror (errno)); - goto out_2; - } - - if (fileb->ob_id != b->ob_id || - fileb->ob_oid != b->ob_oid || - fileb->ob_npeers != b->ob_npeers || - fileb->ob_count >= b->ob_npeers || - (fileb->ob_ordinal != b->ob_ordinal - 1 && - fileb->ob_ordinal != b->ob_ordinal)) { - fprintf (stderr, "obdio_barrier "LPX64": corrupt\n", b->ob_id); - fprintf (stderr, " got ["LPX64","LPX64","LPX64","LPX64","LPX64"]\n", - fileb->ob_id, fileb->ob_oid, fileb->ob_npeers, - fileb->ob_ordinal, fileb->ob_count); - fprintf (stderr, " expected ["LPX64","LPX64","LPX64","LPX64","LPX64"]\n", - b->ob_id, b->ob_oid, b->ob_npeers, - b->ob_ordinal, b->ob_count); - rc = -1; - goto out_2; - } - } - - out_2: - rc2 = obdio_cancel (conn, &lh); - if (rc == 0 && rc2 != 0) { - fprintf (stderr, "obdio_barrier "LPX64": Error on cancel: %s\n", - b->ob_oid, strerror (errno)); - rc = rc2; - } - out_1: - free (space); - out_0: - rc2 = obdio_close (conn, b->ob_oid, &fh); - if (rc == 0 && rc2 != 0) { - fprintf (stderr, "obdio_barrier "LPX64": Error on close: %s\n", - b->ob_oid, strerror (errno)); - rc = rc2; - } - - return (rc); -} - - diff --git a/lustre/utils/obdiolib.h b/lustre/utils/obdiolib.h deleted file mode 100644 index 9b06941..0000000 --- a/lustre/utils/obdiolib.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Copyright (C) 2003 Cluster File Systems, Inc. - * Author: Eric Barton - * - * 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 _OBDIOLIB_H_ -#define _OBDIOLIB_H_ - -#include - -#include -#include - -#include -#include -#include - -struct obdio_conn { - int oc_fd; - uint64_t oc_conn_addr; - uint64_t oc_conn_cookie; - struct obd_ioctl_data oc_data; - char oc_buffer[8192]; -}; - -struct obdio_barrier { - uint64_t ob_id; - uint64_t ob_oid; - uint64_t ob_npeers; - uint64_t ob_ordinal; - uint64_t ob_count; -}; - -extern struct obdio_conn * obdio_connect (int device); -extern void obdio_disconnect (struct obdio_conn *conn); -extern int obdio_open (struct obdio_conn *conn, uint64_t oid, - struct lustre_handle *fh); -extern int obdio_close (struct obdio_conn *conn, uint64_t oid, - struct lustre_handle *fh); -extern int obdio_pread (struct obdio_conn *conn, uint64_t oid, - char *buffer, uint32_t count, uint64_t offset); -extern int obdio_pwrite (struct obdio_conn *conn, uint64_t oid, - char *buffer, uint32_t count, uint64_t offset); -extern int obdio_enqueue (struct obdio_conn *conn, uint64_t oid, - int mode, uint64_t offset, uint32_t count, - struct lustre_handle *lh); -extern int obdio_cancel (struct obdio_conn *conn, struct lustre_handle *lh); -extern void *obdio_alloc_aligned_buffer (void **spacep, int size); -extern struct obdio_barrier *obdio_new_barrier (uint64_t oid, uint64_t id, int npeers) ; -extern int obdio_setup_barrier (struct obdio_conn *conn, struct obdio_barrier *b); -extern int obdio_barrier (struct obdio_conn *conn, struct obdio_barrier *b); - -#endif diff --git a/lustre/utils/obdstat.c b/lustre/utils/obdstat.c deleted file mode 100644 index 01085b9..0000000 --- a/lustre/utils/obdstat.c +++ /dev/null @@ -1,198 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -struct one_stat { - char *name; - int fd; - long long current; - long long delta; -}; - -struct one_stat *read_bytes; -struct one_stat *read_reqs; -struct one_stat *write_bytes; -struct one_stat *write_reqs; -struct one_stat *getattr_reqs; -struct one_stat *setattr_reqs; -struct one_stat *create_reqs; -struct one_stat *destroy_reqs; -struct one_stat *statfs_reqs; -struct one_stat *open_reqs; -struct one_stat *close_reqs; -struct one_stat *punch_reqs; - -struct one_stat * -init_one_stat (char *basename, char *name) -{ - char fname[1024]; - struct one_stat *stat = (struct one_stat *)malloc (sizeof (*stat)); - - if (stat == NULL) { - fprintf (stderr, "Can't allocate stat %s: %s\n", - name, strerror (errno)); - abort (); - } - - snprintf (fname, sizeof (fname), "%s/%s", basename, name); - - memset (stat, 0, sizeof (*stat)); - stat->name = name; - - stat->fd = open (fname, O_RDONLY); - if (stat->fd < 0 ) { - fprintf (stderr, "Can't open stat %s: %s\n", - fname, strerror (errno)); - abort (); - } - - return (stat); -} - -void -update_one_stat (struct one_stat *stat) -{ - static char buffer[1024]; - long long prev = stat->current; - int nob; - - lseek (stat->fd, 0, SEEK_SET); - nob = read (stat->fd, buffer, sizeof (buffer) - 1); - if (nob < 0) { - fprintf (stderr, "Can't read stat %s: %s\n", - stat->name, strerror (errno)); - abort (); - } - - buffer[nob] = 0; - if (sscanf (buffer, "%Ld", &stat->current) != 1) { - fprintf (stderr, "Can't parse stat %s: %s\n", - stat->name, strerror (errno)); - abort (); - } - - stat->delta = stat->current - prev; -} - -double -timenow () -{ - struct timeval tv; - - gettimeofday (&tv, NULL); - return (tv.tv_sec + tv.tv_usec / 1000000.0); -} - -void -do_stat (void) -{ - static double last = 0.0; - double now; - double t; - - now = timenow(); - - update_one_stat (read_bytes); - update_one_stat (read_reqs); - update_one_stat (write_bytes); - update_one_stat (write_reqs); - update_one_stat (getattr_reqs); - update_one_stat (setattr_reqs); - update_one_stat (open_reqs); - update_one_stat (close_reqs); - update_one_stat (create_reqs); - update_one_stat (destroy_reqs); - update_one_stat (statfs_reqs); - update_one_stat (punch_reqs); - - if (last == 0.0) { - printf ("R %Ld/%Ld W %Ld/%Ld attr %Ld/%Ld open %Ld/%Ld create %Ld/%Ld stat %Ld punch %Ld\n", - read_bytes->current, read_reqs->current, - write_bytes->current, write_reqs->current, - getattr_reqs->current, setattr_reqs->current, - open_reqs->current, close_reqs->current, - create_reqs->current, destroy_reqs->current, - statfs_reqs->current, punch_reqs->current); - } else { - t = now - last; - - printf ("R %6Ld (%5d %6.2fMb)/s W %6Ld (%5d %6.2fMb)/s", - read_reqs->delta, (int)(read_reqs->delta / t), - read_bytes->delta / ((1<<20) * t), - write_reqs->delta, (int)(write_reqs->delta / t), - write_bytes->delta / ((1<<20) * t)); - - if (getattr_reqs->delta != 0) - printf (" ga:%Ld,%d/s", getattr_reqs->delta, - (int)(getattr_reqs->delta / t)); - - if (setattr_reqs->delta != 0) - printf (" sa:%Ld", setattr_reqs->delta); - - if (open_reqs->delta != 0) - printf (" op:%Ld", open_reqs->delta); - - if (close_reqs->delta != 0) - printf (" cl:%Ld", close_reqs->delta); - - if (create_reqs->delta != 0) - printf (" cx:%Ld", create_reqs->delta); - - if (destroy_reqs->delta != 0) - printf (" dx:%Ld", destroy_reqs->delta); - - if (statfs_reqs->delta != 0) - printf (" st:%Ld", statfs_reqs->delta); - - if (punch_reqs->delta != 0) - printf (" pu:%Ld", punch_reqs->delta); - - printf ("\n"); - } - - fflush(stdout); - last = timenow(); -} - -int main (int argc, char **argv) -{ - char basedir[128]; - int interval = 0; - - if (argc < 2) { - fprintf (stderr, "obd type not specified\n"); - return (1); - } - - snprintf (basedir, sizeof (basedir), "/proc/sys/%s", argv[1]); - - if (argc > 2) - interval = atoi (argv[2]); - - read_bytes = init_one_stat (basedir, "read_bytes"); - read_reqs = init_one_stat (basedir, "read_reqs"); - write_bytes = init_one_stat (basedir, "write_bytes"); - write_reqs = init_one_stat (basedir, "write_reqs"); - getattr_reqs = init_one_stat (basedir, "getattr_reqs"); - setattr_reqs = init_one_stat (basedir, "setattr_reqs"); - create_reqs = init_one_stat (basedir, "create_reqs"); - destroy_reqs = init_one_stat (basedir, "destroy_reqs"); - statfs_reqs = init_one_stat (basedir, "statfs_reqs"); - open_reqs = init_one_stat (basedir, "open_reqs"); - close_reqs = init_one_stat (basedir, "close_reqs"); - punch_reqs = init_one_stat (basedir, "punch_reqs"); - - do_stat (); - - if (interval == 0) - return (0); - - for (;;) { - sleep (interval); - do_stat (); - } -} 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